home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Freeware 2002 November
/
SGI Freeware 2002 November - Disc 2.iso
/
dist
/
fw_glimpse.idb
/
usr
/
freeware
/
src
/
glimpse-3.0
/
agrep
/
agrep.c.z
/
agrep.c
Wrap
C/C++ Source or Header
|
1997-09-09
|
103KB
|
3,445 lines
/*
* bgopal: (1993-4) added a library interface and removed some bugs: also
* selectively modified many routines to work with our text-compression algo.
*/
#include "agrep.h"
#include "checkfile.h"
#define PRINT(s)
extern char **environ;
extern int errno;
int pattern_index; /* index in argv where the pattern is */
int glimpse_isserver=0; /* so that there is no user interaction */
int glimpse_call = 0; /* So that usage message is not printed twice */
int glimpse_clientdied=0;/* to quit search if glimpseserver's client dies */
int agrep_initialfd; /* Where does input come from? File/Memory? */
CHAR *agrep_inbuffer;
int agrep_inlen;
int agrep_inpointer;
FILE *agrep_finalfp; /* Where does output go to? File/Memory? */
CHAR *agrep_outbuffer;
int agrep_outlen;
int agrep_outpointer;
int execfd; /* used by exec called within agrep_search, set in agrep_init */
int multifd = -1; /* fd for multipattern search used in ^^ , set in ^^^^^^^^ */
extern char *pat_spool;
#if DOTCOMPRESSED
extern char *tc_pat_spool;
#endif /* DOTCOMPRESSED */
char *multibuf=NULL; /* buffer to put the multiple patterns in */
int multilen = 0; /* length of the multibuf: not the #of multi-patterns! */
extern int pos_cnt; /* to re-initialize it to 0 for reg-exp search */
unsigned Mask[MAXSYM];
unsigned Init1, NO_ERR_MASK, Init[MaxError];
unsigned Bit[WORD+1];
CHAR buffer[BlockSize+Maxline+1]; /* should not be used anywhere: 10/18/93 */
unsigned Next[MaxNext], Next1[MaxNext];
unsigned wildmask, endposition, D_endpos;
int LIMITOUTPUT; /* maximum number of matches we are going to allow */
int LIMITPERFILE; /* maximum number of matches per file we are going to allow */
int LIMITTOTALFILE; /* maximum number of files we are going to allow */
int EXITONERROR; /* return -1 or exit on error? */
int REGEX, FASTREGEX, RE_ERR, FNAME, WHOLELINE, SIMPLEPATTERN;
int COUNT, HEAD, TAIL, LINENUM, INVERSE, I, S, DD, AND, SGREP, JUMP;
int NOOUTPUTZERO;
int Num_Pat, PSIZE, prev_num_of_matched, num_of_matched, files_matched, SILENT, NOPROMPT, BESTMATCH, NOUPPER;
int NOMATCH, TRUNCATE, FIRST_IN_RE, FIRSTOUTPUT;
int WORDBOUND, DELIMITER, D_length, tc_D_length, original_D_length;
int EATFIRST, OUTTAIL;
int BYTECOUNT;
int PRINTOFFSET;
int PRINTRECORD;
int FILEOUT;
int DNA;
int APPROX;
int PAT_FILE; /* multiple patterns from a given file */
char PAT_FILE_NAME[MAX_LINE_LEN];
int PAT_BUFFER; /* multiple patterns from a given buffer */
int CONSTANT;
int RECURSIVE;
int total_line; /* used in mgrep */
int D;
int M;
int TCOMPRESSED;
int EASYSEARCH; /* 1 used only for compressed files: LITTLE/BIG */
int ALWAYSFILENAME = OFF;
int POST_FILTER = OFF;
int NEW_FILE = OFF; /* only when post-filter is used */
int PRINTFILENUMBER = OFF;
int PRINTPATTERN = OFF;
int MULTI_OUTPUT = OFF; /* should mgrep print the matched line multiple times for each matched pattern or just once? */
/* invisible to the user, used only by glimpse: cannot use -l since it is incompatible with stdin and -A is used for the index search (done next) */
/* Stuff to handle complicated boolean patterns */
int AComplexBoolean = 0;
ParseTree *AParse = NULL;
int anum_terminals = 0;
ParseTree aterminals[MAXNUM_PAT];
char amatched_terminals[MAXNUM_PAT];
#if MEASURE_TIMES
/* timing variables */
int OUTFILTER_ms;
int FILTERALGO_ms;
int INFILTER_ms;
#endif /*MEASURE_TIMES*/
CHAR **Textfiles = NULL; /* array of filenames to be searched */
int Numfiles = 0; /* indicates how many files in Textfiles */
int copied_from_argv = 0; /* were filenames copied from argv (should I free 'em)? */
CHAR old_D_pat[MaxDelimit * 2] = "\n"; /* to hold original D_pattern */
CHAR original_old_D_pat[MaxDelimit * 2] = "\n";
CHAR Pattern[MAXPAT], OldPattern[MAXPAT];
CHAR CurrentFileName[MAX_LINE_LEN];
int SetCurrentFileName = 0; /* dirty glimpse trick to make filters work: output seems to come from another file */
int CurrentByteOffset;
int SetCurrentByteOffset = 0;
CHAR Progname[MAXNAME];
CHAR D_pattern[MaxDelimit * 2] = "\n; "; /* string which delimits records -- defaults to newline */
CHAR tc_D_pattern[MaxDelimit * 2] = "\n";
CHAR original_D_pattern[MaxDelimit * 2] = "\n; ";
char COMP_DIR[MAX_LINE_LEN];
char FREQ_FILE[MAX_LINE_LEN], HASH_FILE[MAX_LINE_LEN], STRING_FILE[MAX_LINE_LEN]; /* interfacing with tcompress */
int NOFILENAME, /* Boolean flag, set for -h option */
FILENAMEONLY;/* Boolean flag, set for -l option */
extern int init();
int table[WORD][WORD];
CHAR *agrep_saved_pattern = NULL; /* to prevent multiple prepfs for each boolean search: crd@hplb.hpl.hp.com */
/* Called when multipattern search and pattern has not changed */
void
reinit_value_partial()
{
num_of_matched = prev_num_of_matched = 0;
errno = 0;
FIRST_IN_RE = ON;
}
/* This must be called before every agrep_search to reset agrep globals */
void
reinit_value()
{
int i, j;
/* Added on 7th Oct 194 */
if (AParse) {
if (AComplexBoolean) destroy_tree(AParse);
AComplexBoolean = 0;
AParse = 0;
PAT_BUFFER = 0;
if (multibuf != NULL) free(multibuf); /* this was allocated for arbit booleans, not multipattern search */
multibuf = NULL;
multilen = 0;
/* Cannot free multifd here since that is always allocated for multipattern search */
}
for (i=0; i<anum_terminals; i++) {
free(aterminals[i].data.leaf.value);
memset(&aterminals[i], '\0', sizeof(ParseTree));
}
anum_terminals = 0;
Bit[WORD] = 1;
for (i = WORD - 1; i > 0 ; i--) Bit[i] = Bit[i+1] << 1;
for (i=0; i< MAXSYM; i++) Mask[i] = 0;
/* bg: new things added on Mar 13 94 */
Init1 = 0;
NO_ERR_MASK = 0;
memset(Init, '\0', MaxError * sizeof(unsigned));
memset(Next, '\0', MaxNext * sizeof(unsigned));
memset(Next1, '\0', MaxNext * sizeof(unsigned));
wildmask = endposition = D_endpos = 0;
for (i=0; i<WORD; i++)
for (j=0; j<WORD; j++)
table[i][j] = 0;
strcpy(D_pattern, original_D_pattern);
D_length = original_D_length;
strcpy(old_D_pat, original_old_D_pat);
/* Changed on Dec 26th: bg */
FASTREGEX = REGEX = 0;
HEAD = TAIL = ON; /* were off initially */
RE_ERR = 0;
AND = 0;
M = 0;
pos_cnt = 0; /* added 31 Jan 95 */
reinit_value_partial();
}
/* This must be called before every agrep_init to reset agrep options */
void
initial_value()
{
SetCurrentFileName = 0; /* 16/9/94 */
SetCurrentByteOffset = 0; /* 23/9/94 */
/* courtesy: crd@hplb.hpl.hp.com */
if (agrep_saved_pattern) {
free(agrep_saved_pattern);
agrep_saved_pattern= NULL;
}
/* bg: new stuff on 17/Feb/94 */
if (multifd != -1) close(multifd);
multifd = -1;
if (multibuf != NULL) free(multibuf);
multibuf = NULL;
multilen = 0;
if (pat_spool != NULL) free(pat_spool);
pat_spool = NULL;
#if DOTCOMPRESSED
if (tc_pat_spool != NULL) free(tc_pat_spool);
tc_pat_spool = NULL;
#endif /* DOTCOMPRESSED */
LIMITOUTPUT = 0; /* means infinity = current semantics */
LIMITPERFILE = 0; /* means infinity = current semantics */
LIMITTOTALFILE = 0; /* means infinity = current semantics */
EASYSEARCH = 1;
DNA = APPROX = PAT_FILE = PAT_BUFFER = CONSTANT = total_line = D = TCOMPRESSED = 0;
PAT_FILE_NAME[0] = '\0';
EXITONERROR = NOFILENAME = FILENAMEONLY = FILEOUT = ALWAYSFILENAME = NEW_FILE = POST_FILTER = 0;
original_old_D_pat[0] = old_D_pat[0] = '\n';
original_old_D_pat[1] = old_D_pat[1] = '\0';
original_D_pattern[0] = D_pattern[0] = '\n';
original_D_pattern[1] = D_pattern[1] = ';';
original_D_pattern[2] = D_pattern[2] = ' ';
original_D_pattern[3] = D_pattern[3] = '\0';
strcpy(tc_D_pattern, "\n");
tc_D_length = 1;
/* the functions agrep_init and agrep_search take care of Textfiles and Numfiles */
agrep_inpointer = 0;
agrep_outpointer = 0;
agrep_outlen = 0;
#if MEASURE_TIMES
OUTFILTER_ms = FILTERALGO_ms = INFILTER_ms = 0;
#endif /*MEASURE_TIMES*/
MULTI_OUTPUT = 0;
PRINTPATTERN = 0;
PRINTFILENUMBER = 0;
JUMP = FNAME = BESTMATCH = NOPROMPT = NOUPPER = 0;
RECURSIVE = 0;
COUNT = LINENUM = WHOLELINE = SGREP = 0;
NOOUTPUTZERO = 0;
EATFIRST = INVERSE = TRUNCATE = OUTTAIL = 0;
NOMATCH = FIRSTOUTPUT = ON; /* were off initally */
I = DD = S = 1; /* were off initially */
original_D_length = D_length = 2; /* was 0 initially */
SILENT = Num_Pat = PSIZE = SIMPLEPATTERN = prev_num_of_matched = num_of_matched = files_matched = 0;
WORDBOUND = DELIMITER = 0;
COMP_DIR[0] = '\0';
FREQ_FILE[0] = '\0';
HASH_FILE[0] = '\0';
STRING_FILE[0] = '\0';
BYTECOUNT = OFF;
PRINTOFFSET = OFF;
PRINTRECORD = ON;
glimpse_clientdied = 0; /* added 15th Feb 95 */
/* Pattern, OldPattern, execfd, Numfiles are set in agrep_init: so no need to initialize */
reinit_value();
}
void
compute_next(M, Next, Next1)
int M;
unsigned *Next, *Next1;
{
int i, j=0, n, k, temp;
int mid, pp;
int MM, base;
unsigned V[WORD];
base = WORD - M;
temp = Bit[base];
Bit[base] = 0;
for (i=0; i<WORD; i++) V[i] = 0;
for (i=1; i<M; i++)
{
j=0;
while (table[i][j] > 0 && j < 10) {
V[i] = V[i] | Bit[base + table[i][j++]];
}
}
Bit[base]=temp;
if(M <= SHORTREG)
{
k = exponen(M);
pp = 2*k;
for(i=k; i<pp ; i++)
{
n = i;
Next[i]= (k>>1);
for(j=M; j>=1; j--)
{
if(n & Bit[WORD]) Next[i] = Next[i] | V[j];
n = (n>>1);
}
}
return;
}
if(M > MAXREG) fprintf(stderr, "%s: regular expression too long\n", Progname);
MM = M;
if(M & 1) M=M+1;
k = exponen(M/2);
pp = 2*k;
mid = MM/2;
for(i=k; i<pp ; i++)
{
n = i;
Next[i]= (Bit[base]>>1);
for(j=MM; j>mid ; j--)
{
if(n & Bit[WORD]) Next[i] = Next[i] | V[j-mid];
n = (n>>1);
}
n=i-k;
Next1[i-k] = 0;
for(j = 0; j<mid; j++)
{
if(n & Bit[WORD]) Next1[i-k] = Next1[i-k] | V[MM-j];
n = (n>>1);
}
}
return;
}
int
exponen(m)
int m;
{
int i, ex;
ex= 1;
for (i=0; i<m; i++) ex <<= 1; /* was ex *= 2 */
return(ex);
}
int
re1(Text, M, D)
int Text, M, D;
{
register unsigned i, c, r0, r1, r2, r3, CMask, Newline, Init0, r_NO_ERR;
register unsigned end;
register unsigned hh, LL=0, k; /* Lower part */
int FIRST_TIME=ON, num_read , j=0, base;
unsigned A[MaxRerror+1], B[MaxRerror+1];
unsigned Next[MaxNext], Next1[MaxNext];
CHAR *buffer;
int FIRST_LOOP = 1;
r_NO_ERR = NO_ERR_MASK;
if(M > 30) {
fprintf(stderr, "%s: regular expression too long\n", Progname);
if (!EXITONERROR){
errno = AGREP_ERROR;
return -1;
}
else exit(2);
}
base = WORD - M;
hh = M/2;
for(i=WORD, j=0; j < hh ; i--, j++) LL = LL | Bit[i];
if(FIRST_IN_RE) compute_next(M, Next, Next1);
/*SUN: try: change to memory allocation */
FIRST_IN_RE = 0;
Newline = '\n';
Init[0] = Bit[base];
if(HEAD) Init[0] = Init[0] | Bit[base+1];
for(i=1; i<= D; i++) Init[i] = Init[i-1] | Next[Init[i-1]>>hh] | Next1[Init[i-1]&LL];
Init1 = Init[0] | 1;
Init0 = Init[0];
r2 = r3 = Init[0];
for(k=0; k<= D; k++) {
A[k] = B[k] = Init[k];
}
if ( D == 0 )
{
#if AGREP_POINTER
if (Text != -1)
{
#endif /*AGREP_POINTER*/
alloc_buf(Text, &buffer, BlockSize+Maxline+1);
while ((num_read = fill_buf(Text, buffer + Maxline, BlockSize)) > 0)
{
i=Maxline;
end = num_read + Maxline;
if((num_read < BlockSize) && buffer[end-1] != '\n') buffer[end] = '\n';
if(FIRST_LOOP) { /* if first time in the loop add a newline */
buffer[i-1] = '\n'; /* in front the text. */
i--;
CurrentByteOffset --;
FIRST_LOOP = 0;
}
/* RE1_PROCESS_WHEN_DZERO: the while-loop below */
while ( i < end )
{
c = buffer[i++];
CurrentByteOffset ++;
CMask = Mask[c];
if(c != Newline)
{
if(CMask != 0) {
r1 = Init1 & r3;
r2 = ((Next[r3>>hh] | Next1[r3&LL]) & CMask) | r1;
}
else {
r2 = r3 & Init1;
}
}
else {
j++;
if (DELIMITER) CurrentByteOffset -= D_length;
else CurrentByteOffset -= 1;
r1 = Init1 & r3; /* match against endofline */
r2 = ((Next[r3>>hh] | Next1[r3&LL]) & CMask) | r1;
if(TAIL) r2 = (Next[r2>>hh] | Next1[r2&LL]) | r2; /* epsilon move */
if(( r2 & 1 ) ^ INVERSE) {
if(FILENAMEONLY && (NEW_FILE || !POST_FILTER)) {
num_of_matched++;
if (agrep_finalfp != NULL)
fprintf(agrep_finalfp, "%s\n", CurrentFileName);
else {
int outindex;
for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
(CurrentFileName[outindex] != '\0'); outindex++) {
agrep_outbuffer[agrep_outpointer+outindex] = CurrentFileName[outindex];
}
if ((CurrentFileName[outindex] != '\0') || (outindex+agrep_outpointer+1>=agrep_outlen)) {
OUTPUT_OVERFLOW;
free_buf(Text, buffer);
return -1;
}
else agrep_outbuffer[agrep_outpointer+outindex++] = '\n';
agrep_outpointer += outindex;
}
free_buf(Text, buffer);
NEW_FILE = OFF;
return 0;
}
if (-1 == r_output(buffer, i-1, end, j)) {free_buf(Text, buffer); return -1;}
if (((LIMITOUTPUT > 0) && (LIMITOUTPUT <= num_of_matched)) ||
((LIMITPERFILE > 0) && (LIMITPERFILE <= num_of_matched - prev_num_of_matched))) {
free_buf(Text, buffer);
return 0; /* done */
}
}
r3 = Init0;
r2 = (Next[r3>>hh] | Next1[r3&LL]) & CMask | Init0;
/* match begin of line */
if (DELIMITER) CurrentByteOffset += 1*D_length;
else CurrentByteOffset += 1*1;
}
c = buffer[i++];
CurrentByteOffset ++;
CMask = Mask[c];
if(c != Newline)
{
if(CMask != 0) {
r1 = Init1 & r2;
r3 = ((Next[r2>>hh] | Next1[r2&LL]) & CMask) | r1;
}
else r3 = r2 & Init1;
} /* if(NOT Newline) */
else {
j++;
if (DELIMITER) CurrentByteOffset -= D_length;
else CurrentByteOffset -= 1;
r1 = Init1 & r2; /* match against endofline */
r3 = ((Next[r2>>hh] | Next1[r2&LL]) & CMask) | r1;
if(TAIL) r3 = ( Next[r3>>hh] | Next1[r3&LL] ) | r3;
/* epsilon move */
if(( r3 & 1 ) ^ INVERSE) {
if(FILENAMEONLY && (NEW_FILE || !POST_FILTER)) {
num_of_matched++;
if (agrep_finalfp != NULL)
fprintf(agrep_finalfp, "%s\n", CurrentFileName);
else {
int outindex;
for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
(CurrentFileName[outindex] != '\0'); outindex++) {
agrep_outbuffer[agrep_outpointer+outindex] = CurrentFileName[outindex];
}
if ((CurrentFileName[outindex] != '\0') || (outindex+agrep_outpointer+1>=agrep_outlen)) {
OUTPUT_OVERFLOW;
free_buf(Text, buffer);
return -1;
}
else agrep_outbuffer[agrep_outpointer+outindex++] = '\n';
agrep_outpointer += outindex;
}
free_buf(Text, buffer);
NEW_FILE = OFF;
return 0;
}
if (-1 == r_output(buffer, i-1, end, j)) {free_buf(Text, buffer); return -1;}
if (((LIMITOUTPUT > 0) && (LIMITOUTPUT <= num_of_matched)) ||
((LIMITPERFILE > 0) && (LIMITPERFILE <= num_of_matched - prev_num_of_matched))) {
free_buf(Text, buffer);
return 0; /* done */
}
}
r2 = Init0;
r3 = ((Next[r2>>hh] | Next1[r2&LL]) & CMask) | Init0;
/* match begin of line */
if (DELIMITER) CurrentByteOffset += 1*D_length;
else CurrentByteOffset += 1*1;
}
} /* while i < end ... */
strncpy(buffer, buffer+num_read, Maxline);
} /* end while fill_buf()... */
free_buf(Text, buffer);
return 0;
#if AGREP_POINTER
}
else { /* within the memory buffer: assume it starts with a newline at position 0, the actual pattern follows that, and it ends with a '\n' */
num_read = agrep_inlen;
buffer = (CHAR *)agrep_inbuffer;
end = num_read;
/* buffer[end-1] = '\n';*/ /* at end of the text. */
/* buffer[0] = '\n';*/ /* in front of the text. */
i = 0;
/* An exact copy of the above RE1_PROCESS_WHEN_DZERO: the while-loop below */
while ( i < end )
{
c = buffer[i++];
CurrentByteOffset ++;
CMask = Mask[c];
if(c != Newline)
{
if(CMask != 0) {
r1 = Init1 & r3;
r2 = ((Next[r3>>hh] | Next1[r3&LL]) & CMask) | r1;
}
else {
r2 = r3 & Init1;
}
}
else {
j++;
if (DELIMITER) CurrentByteOffset -= D_length;
else CurrentByteOffset -= 1;
r1 = Init1 & r3; /* match against endofline */
r2 = ((Next[r3>>hh] | Next1[r3&LL]) & CMask) | r1;
if(TAIL) r2 = (Next[r2>>hh] | Next1[r2&LL]) | r2; /* epsilon move */
if(( r2 & 1 ) ^ INVERSE) {
if(FILENAMEONLY && (NEW_FILE || !POST_FILTER)) {
num_of_matched++;
if (agrep_finalfp != NULL)
fprintf(agrep_finalfp, "%s\n", CurrentFileName);
else {
int outindex;
for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
(CurrentFileName[outindex] != '\0'); outindex++) {
agrep_outbuffer[agrep_outpointer+outindex] = CurrentFileName[outindex];
}
if ((CurrentFileName[outindex] != '\0') || (outindex+agrep_outpointer+1>=agrep_outlen)) {
OUTPUT_OVERFLOW;
free_buf(Text, buffer);
return -1;
}
else agrep_outbuffer[agrep_outpointer+outindex++] = '\n';
agrep_outpointer += outindex;
}
free_buf(Text, buffer);
NEW_FILE = OFF;
return 0;
}
if (-1 == r_output(buffer, i-1, end, j)) {free_buf(Text, buffer); return -1;}
if (((LIMITOUTPUT > 0) && (LIMITOUTPUT <= num_of_matched)) ||
((LIMITPERFILE > 0) && (LIMITPERFILE <= num_of_matched - prev_num_of_matched))) {
free_buf(Text, buffer);
return 0; /* done */
}
}
r3 = Init0;
r2 = (Next[r3>>hh] | Next1[r3&LL]) & CMask | Init0;
/* match begin of line */
if (DELIMITER) CurrentByteOffset += 1*D_length;
else CurrentByteOffset += 1*1;
}
c = buffer[i++];
CurrentByteOffset ++;
CMask = Mask[c];
if(c != Newline)
{
if(CMask != 0) {
r1 = Init1 & r2;
r3 = ((Next[r2>>hh] | Next1[r2&LL]) & CMask) | r1;
}
else r3 = r2 & Init1;
} /* if(NOT Newline) */
else {
j++;
if (DELIMITER) CurrentByteOffset -= D_length;
else CurrentByteOffset -= 1;
r1 = Init1 & r2; /* match against endofline */
r3 = ((Next[r2>>hh] | Next1[r2&LL]) & CMask) | r1;
if(TAIL) r3 = ( Next[r3>>hh] | Next1[r3&LL] ) | r3;
/* epsilon move */
if(( r3 & 1 ) ^ INVERSE) {
if(FILENAMEONLY && (NEW_FILE || !POST_FILTER)) {
num_of_matched++;
if (agrep_finalfp != NULL)
fprintf(agrep_finalfp, "%s\n", CurrentFileName);
else {
int outindex;
for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
(CurrentFileName[outindex] != '\0'); outindex++) {
agrep_outbuffer[agrep_outpointer+outindex] = CurrentFileName[outindex];
}
if ((CurrentFileName[outindex] != '\0') || (outindex+agrep_outpointer+1>=agrep_outlen)) {
OUTPUT_OVERFLOW;
free_buf(Text, buffer);
return -1;
}
else agrep_outbuffer[agrep_outpointer+outindex++] = '\n';
agrep_outpointer += outindex;
}
free_buf(Text, buffer);
NEW_FILE = OFF;
return 0;
}
if (-1 == r_output(buffer, i-1, end, j)) {free_buf(Text, buffer); return -1;}
if (((LIMITOUTPUT > 0) && (LIMITOUTPUT <= num_of_matched)) ||
((LIMITPERFILE > 0) && (LIMITPERFILE <= num_of_matched - prev_num_of_matched))) {
free_buf(Text, buffer);
return 0; /* done */
}
}
r2 = Init0;
r3 = ((Next[r2>>hh] | Next1[r2&LL]) & CMask) | Init0;
/* match begin of line */
if (DELIMITER) CurrentByteOffset += 1*D_length;
else CurrentByteOffset += 1*1;
}
} /* while i < end ... */
return 0;
}
#endif /*AGREP_POINTER*/
} /* end if (D == 0) */
#if AGREP_POINTER
if (Text != -1)
{
#endif /*AGREP_POINTER*/
while ((num_read = fill_buf(Text, buffer + Maxline, BlockSize)) > 0)
{
i=Maxline;
end = Maxline + num_read;
if((num_read < BlockSize) && buffer[end-1] != '\n') buffer[end] = '\n';
if(FIRST_TIME) { /* if first time in the loop add a newline */
buffer[i-1] = '\n'; /* in front the text. */
i--;
CurrentByteOffset --;
FIRST_TIME = 0;
}
/* RE1_PROCESS_WHEN_DNOTZERO: the while loop below */
while (i < end )
{
c = buffer[i];
CMask = Mask[c];
if(c != Newline)
{
if(CMask != 0) {
r2 = B[0];
r1 = Init1 & r2;
A[0] = ((Next[r2>>hh] | Next1[r2&LL]) & CMask) | r1;
r3 = B[1];
r1 = Init1 & r3;
r0 = r2 | A[0]; /* A[0] | B[0] */
A[1] = ((Next[r3>>hh] | Next1[r3&LL]) & CMask) | (( r2 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;
if(D == 1) goto Nextcharfile;
r2 = B[2];
r1 = Init1 & r2;
r0 = r3 | A[1];
A[2] = ((Next[r2>>hh] | Next1[r2&LL]) & CMask) | ((r3 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;
if(D == 2) goto Nextcharfile;
r3 = B[3];
r1 = Init1 & r3;
r0 = r2 | A[2];
A[3] = ((Next[r3>>hh] | Next1[r3&LL]) & CMask) | ((r2 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;
if(D == 3) goto Nextcharfile;
r2 = B[4];
r1 = Init1 & r2;
r0 = r3 | A[3];
A[4] = ((Next[r2>>hh] | Next1[r2&LL]) & CMask) | ((r3 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;
if(D == 4) goto Nextcharfile;
} /* if(CMask) */
else {
r2 = B[0];
A[0] = r2 & Init1;
r3 = B[1];
r1 = Init1 & r3;
r0 = r2 | A[0];
A[1] = ((r2 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;
if(D == 1) goto Nextcharfile;
r2 = B[2];
r1 = Init1 & r2;
r0 = r3 | A[1];
A[2] = ((r3 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;
if(D == 2) goto Nextcharfile;
r3 = B[3];
r1 = Init1 & r3;
r0 = r2 | A[2];
A[3] = ((r2 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;
if(D == 3) goto Nextcharfile;
r2 = B[4];
r1 = Init1 & r2;
r0 = r3 | A[3];
A[4] = ((r3 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;
if(D == 4) goto Nextcharfile;
}
}
else {
j++;
if (DELIMITER) CurrentByteOffset -= D_length;
else CurrentByteOffset -= 1;
r1 = Init1 & B[D]; /* match against endofline */
A[D] = ((Next[B[D]>>hh] | Next1[B[D]&LL]) & CMask) | r1;
if(TAIL) A[D] = ( Next[A[D]>>hh] | Next1[A[D]&LL] ) | A[D];
/* epsilon move */
if(( A[D] & 1 ) ^ INVERSE) {
if(FILENAMEONLY && (NEW_FILE || !POST_FILTER)) {
num_of_matched++;
if (agrep_finalfp != NULL)
fprintf(agrep_finalfp, "%s\n", CurrentFileName);
else {
int outindex;
for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
(CurrentFileName[outindex] != '\0'); outindex++) {
agrep_outbuffer[agrep_outpointer+outindex] = CurrentFileName[outindex];
}
if ((CurrentFileName[outindex] != '\0') || (outindex+agrep_outpointer+1>=agrep_outlen)) {
OUTPUT_OVERFLOW;
free_buf(Text, buffer);
return -1;
}
else agrep_outbuffer[agrep_outpointer+outindex++] = '\n';
agrep_outpointer += outindex;
}
free_buf(Text, buffer);
NEW_FILE = OFF;
return 0;
}
if (-1 == r_output(buffer, i, end, j)) {free_buf(Text, buffer); return -1;}
if (((LIMITOUTPUT > 0) && (LIMITOUTPUT <= num_of_matched)) ||
((LIMITPERFILE > 0) && (LIMITPERFILE <= num_of_matched - prev_num_of_matched))) {
free_buf(Text, buffer);
return 0; /* done */
}
}
for(k=0; k<=D; k++) B[k] = Init[0];
r1 = Init1 & B[0];
A[0] = (( Next[B[0]>>hh] | Next1[B[0]&LL]) & CMask) | r1;
for(k=1; k<=D; k++) {
r3 = B[k];
r1 = Init1 & r3;
r2 = A[k-1] | B[k-1];
A[k] = ((Next[r3>>hh] | Next1[r3&LL]) & CMask) | ((B[k-1] | Next[r2>>hh] | Next1[r2&LL]) & r_NO_ERR) | r1;
}
if (DELIMITER) CurrentByteOffset += 1*D_length;
else CurrentByteOffset += 1*1;
}
Nextcharfile:
i=i+1;
CurrentByteOffset ++;
c = buffer[i];
CMask = Mask[c];
if(c != Newline)
{
if(CMask != 0) {
r2 = A[0];
r1 = Init1 & r2;
B[0] = ((Next[r2>>hh] | Next1[r2&LL]) & CMask) | r1;
r3 = A[1];
r1 = Init1 & r3;
r0 = B[0] | r2;
B[1] = ((Next[r3>>hh] | Next1[r3&LL]) & CMask) | ((r2 | Next[r0>>hh] | Next1[r0&LL]) & r_NO_ERR) | r1 ;
if(D == 1) goto Nextchar1file;
r2 = A[2];
r1 = Init1 & r2;
r0 = B[1] | r3;
B[2] = ((Next[r2>>hh] | Next1[r2&LL]) & CMask) | ((r3 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;
if(D == 2) goto Nextchar1file;
r3 = A[3];
r1 = Init1 & r3;
r0 = B[2] | r2;
B[3] = ((Next[r3>>hh] | Next1[r3&LL]) & CMask) | ((r2 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;
if(D == 3) goto Nextchar1file;
r2 = A[4];
r1 = Init1 & r2;
r0 = B[3] | r3;
B[4] = ((Next[r2>>hh] | Next1[r2&LL]) & CMask) | ((r3 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;
if(D == 4) goto Nextchar1file;
} /* if(CMask) */
else {
r2 = A[0];
B[0] = r2 & Init1;
r3 = A[1];
r1 = Init1 & r3;
r0 = B[0] | r2;
B[1] = ((r2 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;
if(D == 1) goto Nextchar1file;
r2 = A[2];
r1 = Init1 & r2;
r0 = B[1] | r3;
B[2] = ((r3 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;
if(D == 2) goto Nextchar1file;
r3 = A[3];
r1 = Init1 & r3;
r0 = B[2] | r2;
B[3] = ((r2 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;
if(D == 3) goto Nextchar1file;
r2 = A[4];
r1 = Init1 & r2;
r0 = B[3] | r3;
B[4] = ((r3 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;
if(D == 4) goto Nextchar1file;
}
} /* if(NOT Newline) */
else {
j++;
if (DELIMITER) CurrentByteOffset -= D_length;
else CurrentByteOffset -= 1;
r1 = Init1 & A[D]; /* match against endofline */
B[D] = ((Next[A[D]>>hh] | Next1[A[D]&LL]) & CMask) | r1;
if(TAIL) B[D] = ( Next[B[D]>>hh] | Next1[B[D]&LL] ) | B[D];
/* epsilon move */
if(( B[D] & 1 ) ^ INVERSE) {
if(FILENAMEONLY && (NEW_FILE || !POST_FILTER)) {
num_of_matched++;
if (agrep_finalfp != NULL)
fprintf(agrep_finalfp, "%s\n", CurrentFileName);
else {
int outindex;
for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
(CurrentFileName[outindex] != '\0'); outindex++) {
agrep_outbuffer[agrep_outpointer+outindex] = CurrentFileName[outindex];
}
if ((CurrentFileName[outindex] != '\0') || (outindex+agrep_outpointer+1>=agrep_outlen)) {
OUTPUT_OVERFLOW;
free_buf(Text, buffer);
return -1;
}
else agrep_outbuffer[agrep_outpointer+outindex++] = '\n';
agrep_outpointer += outindex;
}
free_buf(Text, buffer);
NEW_FILE = OFF;
return 0;
}
if (-1 == r_output(buffer, i, end, j)) {free_buf(Text, buffer); return -1;}
if (((LIMITOUTPUT > 0) && (LIMITOUTPUT <= num_of_matched)) ||
((LIMITPERFILE > 0) && (LIMITPERFILE <= num_of_matched - prev_num_of_matched))) {
free_buf(Text, buffer);
return 0; /* done */
}
}
for(k=0; k<=D; k++) A[k] = Init0;
r1 = Init1 & A[0];
B[0] = ((Next[A[0]>>hh] | Next1[A[0]&LL]) & CMask) | r1;
for(k=1; k<=D; k++) {
r3 = A[k];
r1 = Init1 & r3;
r2 = A[k-1] | B[k-1];
B[k] = ((Next[r3>>hh] | Next1[r3&LL]) & CMask) | ((A[k-1] | Next[r2>>hh] | Next1[r2&LL]) & r_NO_ERR) | r1;
}
if (DELIMITER) CurrentByteOffset += 1*D_length;
else CurrentByteOffset += 1*1;
}
Nextchar1file:
i=i+1;
CurrentByteOffset ++;
} /* while i < end */
strncpy(buffer, buffer+num_read, Maxline);
} /* while fill_buf... */
free_buf(Text, buffer);
return 0;
#if AGREP_POINTER
}
else { /* within the memory buffer: assume it starts with a newline at position 0, the actual pattern follows that, and it ends with a '\n' */
num_read = agrep_inlen;
buffer = (CHAR *)agrep_inbuffer;
end = num_read;
/* buffer[end-1] = '\n';*/ /* at end of the text. */
/* buffer[0] = '\n';*/ /* in front of the text. */
i = 0;
/* An exact copy of the above RE1_PROCESS_WHEN_DNOTZERO: the while loop below */
while (i < end )
{
c = buffer[i];
CMask = Mask[c];
if(c != Newline)
{
if(CMask != 0) {
r2 = B[0];
r1 = Init1 & r2;
A[0] = ((Next[r2>>hh] | Next1[r2&LL]) & CMask) | r1;
r3 = B[1];
r1 = Init1 & r3;
r0 = r2 | A[0]; /* A[0] | B[0] */
A[1] = ((Next[r3>>hh] | Next1[r3&LL]) & CMask) | (( r2 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;
if(D == 1) goto Nextcharmem;
r2 = B[2];
r1 = Init1 & r2;
r0 = r3 | A[1];
A[2] = ((Next[r2>>hh] | Next1[r2&LL]) & CMask) | ((r3 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;
if(D == 2) goto Nextcharmem;
r3 = B[3];
r1 = Init1 & r3;
r0 = r2 | A[2];
A[3] = ((Next[r3>>hh] | Next1[r3&LL]) & CMask) | ((r2 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;
if(D == 3) goto Nextcharmem;
r2 = B[4];
r1 = Init1 & r2;
r0 = r3 | A[3];
A[4] = ((Next[r2>>hh] | Next1[r2&LL]) & CMask) | ((r3 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;
if(D == 4) goto Nextcharmem;
} /* if(CMask) */
else {
r2 = B[0];
A[0] = r2 & Init1;
r3 = B[1];
r1 = Init1 & r3;
r0 = r2 | A[0];
A[1] = ((r2 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;
if(D == 1) goto Nextcharmem;
r2 = B[2];
r1 = Init1 & r2;
r0 = r3 | A[1];
A[2] = ((r3 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;
if(D == 2) goto Nextcharmem;
r3 = B[3];
r1 = Init1 & r3;
r0 = r2 | A[2];
A[3] = ((r2 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;
if(D == 3) goto Nextcharmem;
r2 = B[4];
r1 = Init1 & r2;
r0 = r3 | A[3];
A[4] = ((r3 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;
if(D == 4) goto Nextcharmem;
}
}
else {
j++;
if (DELIMITER) CurrentByteOffset -= D_length;
else CurrentByteOffset -= 1;
r1 = Init1 & B[D]; /* match against endofline */
A[D] = ((Next[B[D]>>hh] | Next1[B[D]&LL]) & CMask) | r1;
if(TAIL) A[D] = ( Next[A[D]>>hh] | Next1[A[D]&LL] ) | A[D];
/* epsilon move */
if(( A[D] & 1 ) ^ INVERSE) {
if(FILENAMEONLY && (NEW_FILE || !POST_FILTER)) {
num_of_matched++;
if (agrep_finalfp != NULL)
fprintf(agrep_finalfp, "%s\n", CurrentFileName);
else {
int outindex;
for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
(CurrentFileName[outindex] != '\0'); outindex++) {
agrep_outbuffer[agrep_outpointer+outindex] = CurrentFileName[outindex];
}
if ((CurrentFileName[outindex] != '\0') || (outindex+agrep_outpointer+1>=agrep_outlen)) {
OUTPUT_OVERFLOW;
free_buf(Text, buffer);
return -1;
}
else agrep_outbuffer[agrep_outpointer+outindex++] = '\n';
agrep_outpointer += outindex;
}
free_buf(Text, buffer);
NEW_FILE = OFF;
return 0;
}
if (-1 == r_output(buffer, i, end, j)) {free_buf(Text, buffer); return -1;}
if (((LIMITOUTPUT > 0) && (LIMITOUTPUT <= num_of_matched)) ||
((LIMITPERFILE > 0) && (LIMITPERFILE <= num_of_matched - prev_num_of_matched))) {
free_buf(Text, buffer);
return 0; /* done */
}
}
for(k=0; k<=D; k++) B[k] = Init[0];
r1 = Init1 & B[0];
A[0] = (( Next[B[0]>>hh] | Next1[B[0]&LL]) & CMask) | r1;
for(k=1; k<=D; k++) {
r3 = B[k];
r1 = Init1 & r3;
r2 = A[k-1] | B[k-1];
A[k] = ((Next[r3>>hh] | Next1[r3&LL]) & CMask) | ((B[k-1] | Next[r2>>hh] | Next1[r2&LL]) & r_NO_ERR) | r1;
}
if (DELIMITER) CurrentByteOffset += 1*D_length;
else CurrentByteOffset += 1*1;
}
Nextcharmem:
i=i+1;
CurrentByteOffset ++;
c = buffer[i];
CMask = Mask[c];
if(c != Newline)
{
if(CMask != 0) {
r2 = A[0];
r1 = Init1 & r2;
B[0] = ((Next[r2>>hh] | Next1[r2&LL]) & CMask) | r1;
r3 = A[1];
r1 = Init1 & r3;
r0 = B[0] | r2;
B[1] = ((Next[r3>>hh] | Next1[r3&LL]) & CMask) | ((r2 | Next[r0>>hh] | Next1[r0&LL]) & r_NO_ERR) | r1 ;
if(D == 1) goto Nextchar1mem;
r2 = A[2];
r1 = Init1 & r2;
r0 = B[1] | r3;
B[2] = ((Next[r2>>hh] | Next1[r2&LL]) & CMask) | ((r3 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;
if(D == 2) goto Nextchar1mem;
r3 = A[3];
r1 = Init1 & r3;
r0 = B[2] | r2;
B[3] = ((Next[r3>>hh] | Next1[r3&LL]) & CMask) | ((r2 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;
if(D == 3) goto Nextchar1mem;
r2 = A[4];
r1 = Init1 & r2;
r0 = B[3] | r3;
B[4] = ((Next[r2>>hh] | Next1[r2&LL]) & CMask) | ((r3 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;
if(D == 4) goto Nextchar1mem;
} /* if(CMask) */
else {
r2 = A[0];
B[0] = r2 & Init1;
r3 = A[1];
r1 = Init1 & r3;
r0 = B[0] | r2;
B[1] = ((r2 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;
if(D == 1) goto Nextchar1mem;
r2 = A[2];
r1 = Init1 & r2;
r0 = B[1] | r3;
B[2] = ((r3 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;
if(D == 2) goto Nextchar1mem;
r3 = A[3];
r1 = Init1 & r3;
r0 = B[2] | r2;
B[3] = ((r2 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;
if(D == 3) goto Nextchar1mem;
r2 = A[4];
r1 = Init1 & r2;
r0 = B[3] | r3;
B[4] = ((r3 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;
if(D == 4) goto Nextchar1mem;
}
} /* if(NOT Newline) */
else {
j++;
if (DELIMITER) CurrentByteOffset -= D_length;
else CurrentByteOffset -= 1;
r1 = Init1 & A[D]; /* match against endofline */
B[D] = ((Next[A[D]>>hh] | Next1[A[D]&LL]) & CMask) | r1;
if(TAIL) B[D] = ( Next[B[D]>>hh] | Next1[B[D]&LL] ) | B[D];
/* epsilon move */
if(( B[D] & 1 ) ^ INVERSE) {
if(FILENAMEONLY && (NEW_FILE || !POST_FILTER)) {
num_of_matched++;
if (agrep_finalfp != NULL)
fprintf(agrep_finalfp, "%s\n", CurrentFileName);
else {
int outindex;
for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
(CurrentFileName[outindex] != '\0'); outindex++) {
agrep_outbuffer[agrep_outpointer+outindex] = CurrentFileName[outindex];
}
if ((CurrentFileName[outindex] != '\0') || (outindex+agrep_outpointer+1>=agrep_outlen)) {
OUTPUT_OVERFLOW;
free_buf(Text, buffer);
return -1;
}
else agrep_outbuffer[agrep_outpointer+outindex++] = '\n';
agrep_outpointer += outindex;
}
free_buf(Text, buffer);
NEW_FILE = OFF;
return 0;
}
if (-1 == r_output(buffer, i, end, j)) {free_buf(Text, buffer); return -1;}
if (((LIMITOUTPUT > 0) && (LIMITOUTPUT <= num_of_matched)) ||
((LIMITPERFILE > 0) && (LIMITPERFILE <= num_of_matched - prev_num_of_matched))) {
free_buf(Text, buffer);
return 0; /* done */
}
}
for(k=0; k<=D; k++) A[k] = Init0;
r1 = Init1 & A[0];
B[0] = ((Next[A[0]>>hh] | Next1[A[0]&LL]) & CMask) | r1;
for(k=1; k<=D; k++) {
r3 = A[k];
r1 = Init1 & r3;
r2 = A[k-1] | B[k-1];
B[k] = ((Next[r3>>hh] | Next1[r3&LL]) & CMask) | ((A[k-1] | Next[r2>>hh] | Next1[r2&LL]) & r_NO_ERR) | r1;
}
if (DELIMITER) CurrentByteOffset += 1*D_length;
else CurrentByteOffset += 1*1;
}
Nextchar1mem:
i=i+1;
CurrentByteOffset ++;
} /* while i < end */
return 0;
}
#endif /*AGREP_POINTER*/
} /* re1 */
int
re(Text, M, D)
int Text, M, D;
{
register unsigned i, c, r1, r2, r3, CMask, k, Newline, Init0, Init1, end;
register unsigned r_even, r_odd, r_NO_ERR ;
unsigned RMask[MAXSYM];
unsigned A[MaxRerror+1], B[MaxRerror+1];
int num_read, j=0, lasti, base, ResidueSize;
int FIRST_TIME; /* Flag */
CHAR *buffer;
base = WORD - M;
k = 2*exponen(M);
if(FIRST_IN_RE) {
compute_next(M, Next, Next1);
FIRST_IN_RE = 0;
}
for(i=0; i< MAXSYM; i++) RMask[i] = Mask[i];
r_NO_ERR = NO_ERR_MASK;
Newline = '\n';
Init0 = Init[0] = Bit[base];
if(HEAD) Init0 = Init[0] = Init0 | Bit[base+1] ;
for(i=1; i<= D; i++) Init[i] = Init[i-1] | Next[Init[i-1]]; /* can be out? */
Init1 = Init0 | 1;
r2 = r3 = Init0;
for(k=0; k<= D; k++) {
A[k] = B[k] = Init[0];
} /* can be out? */
FIRST_TIME = ON;
alloc_buf(Text, &buffer, BlockSize+Maxline+1);
if ( D == 0 )
{
#if AGREP_POINTER
if(Text != -1) {
#endif /*AGREP_POINTER*/
lasti = Maxline;
while ((num_read = fill_buf(Text, buffer + Maxline, BlockSize)) > 0)
{
i=Maxline;
end = Maxline + num_read ;
if((num_read < BlockSize)&&buffer[end-1] != '\n') buffer[end] = '\n';
if(FIRST_TIME) {
buffer[i-1] = '\n';
i--;
CurrentByteOffset --;
FIRST_TIME = 0;
}
/* RE_PROCESS_WHEN_DZERO: the while-loop below */
while (i < end)
{
c = buffer[i++];
CurrentByteOffset ++;
CMask = RMask[c];
if(c != Newline)
{
r1 = Init1 & r3;
r2 = (Next[r3] & CMask) | r1;
}
else {
r1 = Init1 & r3; /* match against '\n' */
r2 = Next[r3] & CMask | r1;
j++;
if (DELIMITER) CurrentByteOffset -= D_length;
else CurrentByteOffset -= 1;
if(TAIL) r2 = Next[r2] | r2 ; /* epsilon move */
if(( r2 & 1) ^ INVERSE) {
if(FILENAMEONLY && (NEW_FILE || !POST_FILTER)) {
num_of_matched++;
if (agrep_finalfp != NULL)
fprintf(agrep_finalfp, "%s\n", CurrentFileName);
else {
int outindex;
for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
(CurrentFileName[outindex] != '\0'); outindex++) {
agrep_outbuffer[agrep_outpointer+outindex] = CurrentFileName[outindex];
}
if ((CurrentFileName[outindex] != '\0') || (outindex+agrep_outpointer+1>=agrep_outlen)) {
OUTPUT_OVERFLOW;
free_buf(Text, buffer);
return -1;
}
else agrep_outbuffer[agrep_outpointer+outindex++] = '\n';
agrep_outpointer += outindex;
}
free_buf(Text, buffer);
NEW_FILE = OFF;
return 0;
}
if (-1 == r_output(buffer, i-1, end, j)) {free_buf(Text, buffer); return -1;}
if (((LIMITOUTPUT > 0) && (LIMITOUTPUT <= num_of_matched)) ||
((LIMITPERFILE > 0) && (LIMITPERFILE <= num_of_matched - prev_num_of_matched))) {
free_buf(Text, buffer);
return 0; /* done */
}
}
lasti = i - 1;
r3 = Init0;
r2 = (Next[r3] & CMask) | Init0;
if (DELIMITER) CurrentByteOffset += 1*D_length;
else CurrentByteOffset += 1*1;
}
c = buffer[i++];
CurrentByteOffset ++;
CMask = RMask[c];
if(c != Newline)
{
r1 = Init1 & r2;
r3 = (Next[r2] & CMask) | r1;
}
else {
j++;
if (DELIMITER) CurrentByteOffset -= D_length;
else CurrentByteOffset -= 1;
r1 = Init1 & r2; /* match against endofline */
r3 = Next[r2] & CMask | r1;
if(TAIL) r3 = Next[r3] | r3;
if(( r3 & 1) ^ INVERSE) {
if(FILENAMEONLY && (NEW_FILE || !POST_FILTER)) {
num_of_matched++;
if (agrep_finalfp != NULL)
fprintf(agrep_finalfp, "%s\n", CurrentFileName);
else {
int outindex;
for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
(CurrentFileName[outindex] != '\0'); outindex++) {
agrep_outbuffer[agrep_outpointer+outindex] = CurrentFileName[outindex];
}
if ((CurrentFileName[outindex] != '\0') || (outindex+agrep_outpointer+1>=agrep_outlen)) {
OUTPUT_OVERFLOW;
free_buf(Text, buffer);
return -1;
}
else agrep_outbuffer[agrep_outpointer+outindex++] = '\n';
agrep_outpointer += outindex;
}
free_buf(Text, buffer);
NEW_FILE = OFF;
return 0;
}
if (-1 == r_output(buffer, i-1, end, j)) {free_buf(Text, buffer); return -1;}
if (((LIMITOUTPUT > 0) && (LIMITOUTPUT <= num_of_matched)) ||
((LIMITPERFILE > 0) && (LIMITPERFILE <= num_of_matched - prev_num_of_matched))) {
free_buf(Text, buffer);
return 0; /* done */
}
}
lasti = i - 1;
r2 = Init0;
r3 = (Next[r2] & CMask) | Init0; /* match the newline */
if (DELIMITER) CurrentByteOffset += 1*D_length;
else CurrentByteOffset += 1*1;
}
} /* while */
ResidueSize = Maxline + num_read - lasti;
if(ResidueSize > Maxline) {
ResidueSize = Maxline;
}
strncpy(buffer+Maxline-ResidueSize, buffer+lasti, ResidueSize);
lasti = Maxline - ResidueSize;
} /* while fill_buf() */
free_buf(Text, buffer);
return 0;
#if AGREP_POINTER
}
else {
num_read = agrep_inlen;
buffer = (CHAR *)agrep_inbuffer;
end = num_read;
/* buffer[end-1] = '\n';*/ /* at end of the text. */
/* buffer[0] = '\n';*/ /* in front of the text. */
i = 0;
lasti = 1;
/* An exact copy of the above RE_PROCESS_WHEN_DZERO: the while-loop below */
while (i < end)
{
c = buffer[i++];
CurrentByteOffset ++;
CMask = RMask[c];
if(c != Newline)
{
r1 = Init1 & r3;
r2 = (Next[r3] & CMask) | r1;
}
else {
r1 = Init1 & r3; /* match against '\n' */
r2 = Next[r3] & CMask | r1;
j++;
if (DELIMITER) CurrentByteOffset -= D_length;
else CurrentByteOffset -= 1;
if(TAIL) r2 = Next[r2] | r2 ; /* epsilon move */
if(( r2 & 1) ^ INVERSE) {
if(FILENAMEONLY && (NEW_FILE || !POST_FILTER)) {
num_of_matched++;
if (agrep_finalfp != NULL)
fprintf(agrep_finalfp, "%s\n", CurrentFileName);
else {
int outindex;
for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
(CurrentFileName[outindex] != '\0'); outindex++) {
agrep_outbuffer[agrep_outpointer+outindex] = CurrentFileName[outindex];
}
if ((CurrentFileName[outindex] != '\0') || (outindex+agrep_outpointer+1>=agrep_outlen)) {
OUTPUT_OVERFLOW;
free_buf(Text, buffer);
return -1;
}
else agrep_outbuffer[agrep_outpointer+outindex++] = '\n';
agrep_outpointer += outindex;
}
free_buf(Text, buffer);
NEW_FILE = OFF;
return 0;
}
if (-1 == r_output(buffer, i-1, end, j)) {free_buf(Text, buffer); return -1;}
if (((LIMITOUTPUT > 0) && (LIMITOUTPUT <= num_of_matched)) ||
((LIMITPERFILE > 0) && (LIMITPERFILE <= num_of_matched - prev_num_of_matched))) {
free_buf(Text, buffer);
return 0; /* done */
}
}
lasti = i - 1;
r3 = Init0;
r2 = (Next[r3] & CMask) | Init0;
if (DELIMITER) CurrentByteOffset += 1*D_length;
else CurrentByteOffset += 1*1;
}
c = buffer[i++];
CurrentByteOffset ++;
CMask = RMask[c];
if(c != Newline)
{
r1 = Init1 & r2;
r3 = (Next[r2] & CMask) | r1;
}
else {
j++;
if (DELIMITER) CurrentByteOffset -= D_length;
else CurrentByteOffset -= 1;
r1 = Init1 & r2; /* match against endofline */
r3 = Next[r2] & CMask | r1;
if(TAIL) r3 = Next[r3] | r3;
if(( r3 & 1) ^ INVERSE) {
if(FILENAMEONLY && (NEW_FILE || !POST_FILTER)) {
num_of_matched++;
if (agrep_finalfp != NULL)
fprintf(agrep_finalfp, "%s\n", CurrentFileName);
else {
int outindex;
for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
(CurrentFileName[outindex] != '\0'); outindex++) {
agrep_outbuffer[agrep_outpointer+outindex] = CurrentFileName[outindex];
}
if ((CurrentFileName[outindex] != '\0') || (outindex+agrep_outpointer+1>=agrep_outlen)) {
OUTPUT_OVERFLOW;
free_buf(Text, buffer);
return -1;
}
else agrep_outbuffer[agrep_outpointer+outindex++] = '\n';
agrep_outpointer += outindex;
}
free_buf(Text, buffer);
NEW_FILE = OFF;
return 0;
}
if (-1 == r_output(buffer, i-1, end, j)) {free_buf(Text, buffer); return -1;}
if (((LIMITOUTPUT > 0) && (LIMITOUTPUT <= num_of_matched)) ||
((LIMITPERFILE > 0) && (LIMITPERFILE <= num_of_matched - prev_num_of_matched))) {
free_buf(Text, buffer);
return 0; /* done */
}
}
lasti = i - 1;
r2 = Init0;
r3 = (Next[r2] & CMask) | Init0; /* match the newline */
if (DELIMITER) CurrentByteOffset += 1*D_length;
else CurrentByteOffset += 1*1;
}
} /* while */
/* If a residue is left for within-memory-buffer, since nothing can be "read" after that, we can ignore it: as if only 1 iteration of while */
return 0;
}
#endif /*AGREP_POINTER*/
} /* end if(D==0) */
#if AGREP_POINTER
if (Text != -1) {
#endif /*AGREP_POINTER*/
while ((num_read = fill_buf(Text, buffer + Maxline, BlockSize)) > 0)
{
i=Maxline;
end = Maxline+num_read;
if((num_read < BlockSize) && buffer[end-1] != '\n') buffer[end] = '\n';
if(FIRST_TIME) {
buffer[i-1] = '\n';
i--;
CurrentByteOffset --;
FIRST_TIME = 0;
}
/* RE_PROCESS_WHEN_DNOTZERO: the while-loop below */
while (i < end)
{
c = buffer[i++];
CurrentByteOffset ++;
CMask = RMask[c];
if (c != Newline)
{
r_even = B[0];
r1 = Init1 & r_even;
A[0] = (Next[r_even] & CMask) | r1;
r_odd = B[1];
r1 = Init1 & r_odd;
r2 = (r_even | Next[r_even|A[0]]) &r_NO_ERR;
A[1] = (Next[r_odd] & CMask) | r2 | r1 ;
if(D == 1) goto Nextcharfile;
r_even = B[2];
r1 = Init1 & r_even;
r2 = (r_odd | Next[r_odd|A[1]]) &r_NO_ERR;
A[2] = (Next[r_even] & CMask) | r2 | r1 ;
if(D == 2) goto Nextcharfile;
r_odd = B[3];
r1 = Init1 & r_odd;
r2 = (r_even | Next[r_even|A[2]]) &r_NO_ERR;
A[3] = (Next[r_odd] & CMask) | r2 | r1 ;
if(D == 3) goto Nextcharfile;
r_even = B[4];
r1 = Init1 & r_even;
r2 = (r_odd | Next[r_odd|A[3]]) &r_NO_ERR;
A[4] = (Next[r_even] & CMask) | r2 | r1 ;
goto Nextcharfile;
} /* if NOT Newline */
else {
j++;
if (DELIMITER) CurrentByteOffset -= D_length;
else CurrentByteOffset -= 1;
r1 = Init1 & B[D]; /* match endofline */
A[D] = (Next[B[D]] & CMask) | r1;
if(TAIL) A[D] = Next[A[D]] | A[D];
if((A[D] & 1) ^ INVERSE ) {
if(FILENAMEONLY && (NEW_FILE || !POST_FILTER)) {
num_of_matched++;
if (agrep_finalfp != NULL)
fprintf(agrep_finalfp, "%s\n", CurrentFileName);
else {
int outindex;
for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
(CurrentFileName[outindex] != '\0'); outindex++) {
agrep_outbuffer[agrep_outpointer+outindex] = CurrentFileName[outindex];
}
if ((CurrentFileName[outindex] != '\0') || (outindex+agrep_outpointer+1>=agrep_outlen)) {
OUTPUT_OVERFLOW;
free_buf(Text, buffer);
return -1;
}
else agrep_outbuffer[agrep_outpointer+outindex++] = '\n';
agrep_outpointer += outindex;
}
free_buf(Text, buffer);
NEW_FILE = OFF;
return 0;
}
if (-1 == r_output(buffer, i-1, end, j)) {free_buf(Text, buffer); return -1;}
if (((LIMITOUTPUT > 0) && (LIMITOUTPUT <= num_of_matched)) ||
((LIMITPERFILE > 0) && (LIMITPERFILE <= num_of_matched - prev_num_of_matched))) {
free_buf(Text, buffer);
return 0; /* done */
}
}
for(k=0; k<= D; k++) {
A[k] = B[k] = Init[k];
}
r1 = Init1 & B[0];
A[0] = (Next[B[0]] & CMask) | r1;
for(k=1; k<= D; k++) {
r1 = Init1 & B[k];
r2 = (B[k-1] | Next[A[k-1]|B[k-1]]) &r_NO_ERR;
A[k] = (Next[B[k]] & CMask) | r1 | r2;
}
if (DELIMITER) CurrentByteOffset += 1*D_length;
else CurrentByteOffset += 1*1;
}
Nextcharfile:
c = buffer[i];
CMask = RMask[c];
if(c != Newline)
{
r1 = Init1 & A[0];
B[0] = (Next[A[0]] & CMask) | r1;
r1 = Init1 & A[1];
B[1] = (Next[A[1]] & CMask) | ((A[0] | Next[A[0] | B[0]]) & r_NO_ERR) | r1 ;
if(D == 1) goto Nextchar1file;
r1 = Init1 & A[2];
B[2] = (Next[A[2]] & CMask) | ((A[1] | Next[A[1] | B[1]]) &r_NO_ERR) | r1 ;
if(D == 2) goto Nextchar1file;
r1 = Init1 & A[3];
B[3] = (Next[A[3]] & CMask) | ((A[2] | Next[A[2] | B[2]])&r_NO_ERR) | r1 ;
if(D == 3) goto Nextchar1file;
r1 = Init1 & A[4];
B[4] = (Next[A[4]] & CMask) | ((A[3] | Next[A[3] | B[3]])&r_NO_ERR) | r1 ;
goto Nextchar1file;
} /* if(NOT Newline) */
else {
j++;
if (DELIMITER) CurrentByteOffset -= D_length;
else CurrentByteOffset -= 1;
r1 = Init1 & A[D]; /* match endofline */
B[D] = (Next[A[D]] & CMask) | r1;
if(TAIL) B[D] = Next[B[D]] | B[D];
if((B[D] & 1) ^ INVERSE ) {
if(FILENAMEONLY && (NEW_FILE || !POST_FILTER)) {
num_of_matched++;
if (agrep_finalfp != NULL)
fprintf(agrep_finalfp, "%s\n", CurrentFileName);
else {
int outindex;
for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
(CurrentFileName[outindex] != '\0'); outindex++) {
agrep_outbuffer[agrep_outpointer+outindex] = CurrentFileName[outindex];
}
if ((CurrentFileName[outindex] != '\0') || (outindex+agrep_outpointer+1>=agrep_outlen)) {
OUTPUT_OVERFLOW;
free_buf(Text, buffer);
return -1;
}
else agrep_outbuffer[agrep_outpointer+outindex++] = '\n';
agrep_outpointer += outindex;
}
free_buf(Text, buffer);
NEW_FILE = OFF;
return 0;
}
if (-1 == r_output(buffer, i, end, j)) {free_buf(Text, buffer); return -1;}
if (((LIMITOUTPUT > 0) && (LIMITOUTPUT <= num_of_matched)) ||
((LIMITPERFILE > 0) && (LIMITPERFILE <= num_of_matched - prev_num_of_matched))) {
free_buf(Text, buffer);
return 0; /* done */
}
}
for(k=0; k<= D; k++) {
A[k] = B[k] = Init[k];
}
r1 = Init1 & A[0];
B[0] = (Next[A[0]] & CMask) | r1;
for(k=1; k<= D; k++) {
r1 = Init1 & A[k];
r2 = (A[k-1] | Next[A[k-1]|B[k-1]])&r_NO_ERR;
B[k] = (Next[A[k]] & CMask) | r1 | r2;
}
if (DELIMITER) CurrentByteOffset += 1*D_length;
else CurrentByteOffset += 1*1;
}
Nextchar1file:
i++;
CurrentByteOffset ++;
} /* while i < end */
strncpy(buffer, buffer+num_read, Maxline);
} /* while fill_buf() */
free_buf(Text, buffer);
return 0;
#if AGREP_POINTER
}
else {
num_read = agrep_inlen;
buffer = (CHAR *)agrep_inbuffer;
end = num_read;
/* buffer[end-1] = '\n';*/ /* at end of the text. */
/* buffer[0] = '\n';*/ /* in front of the text. */
i = 0;
/* An exact copy of the above RE_PROCESS_WHEN_DNOTZERO: the while-loop below */
while (i < end)
{
c = buffer[i++];
CurrentByteOffset ++;
CMask = RMask[c];
if (c != Newline)
{
r_even = B[0];
r1 = Init1 & r_even;
A[0] = (Next[r_even] & CMask) | r1;
r_odd = B[1];
r1 = Init1 & r_odd;
r2 = (r_even | Next[r_even|A[0]]) &r_NO_ERR;
A[1] = (Next[r_odd] & CMask) | r2 | r1 ;
if(D == 1) goto Nextcharmem;
r_even = B[2];
r1 = Init1 & r_even;
r2 = (r_odd | Next[r_odd|A[1]]) &r_NO_ERR;
A[2] = (Next[r_even] & CMask) | r2 | r1 ;
if(D == 2) goto Nextcharmem;
r_odd = B[3];
r1 = Init1 & r_odd;
r2 = (r_even | Next[r_even|A[2]]) &r_NO_ERR;
A[3] = (Next[r_odd] & CMask) | r2 | r1 ;
if(D == 3) goto Nextcharmem;
r_even = B[4];
r1 = Init1 & r_even;
r2 = (r_odd | Next[r_odd|A[3]]) &r_NO_ERR;
A[4] = (Next[r_even] & CMask) | r2 | r1 ;
goto Nextcharmem;
} /* if NOT Newline */
else {
j++;
if (DELIMITER) CurrentByteOffset -= D_length;
else CurrentByteOffset -= 1;
r1 = Init1 & B[D]; /* match endofline */
A[D] = (Next[B[D]] & CMask) | r1;
if(TAIL) A[D] = Next[A[D]] | A[D];
if((A[D] & 1) ^ INVERSE ) {
if(FILENAMEONLY && (NEW_FILE || !POST_FILTER)) {
num_of_matched++;
if (agrep_finalfp != NULL)
fprintf(agrep_finalfp, "%s\n", CurrentFileName);
else {
int outindex;
for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
(CurrentFileName[outindex] != '\0'); outindex++) {
agrep_outbuffer[agrep_outpointer+outindex] = CurrentFileName[outindex];
}
if ((CurrentFileName[outindex] != '\0') || (outindex+agrep_outpointer+1>=agrep_outlen)) {
OUTPUT_OVERFLOW;
free_buf(Text, buffer);
return -1;
}
else agrep_outbuffer[agrep_outpointer+outindex++] = '\n';
agrep_outpointer += outindex;
}
free_buf(Text, buffer);
NEW_FILE = OFF;
return 0;
}
if (-1 == r_output(buffer, i-1, end, j)) {free_buf(Text, buffer); return -1;}
if (((LIMITOUTPUT > 0) && (LIMITOUTPUT <= num_of_matched)) ||
((LIMITPERFILE > 0) && (LIMITPERFILE <= num_of_matched - prev_num_of_matched))) {
free_buf(Text, buffer);
return 0; /* done */
}
}
for(k=0; k<= D; k++) {
A[k] = B[k] = Init[k];
}
r1 = Init1 & B[0];
A[0] = (Next[B[0]] & CMask) | r1;
for(k=1; k<= D; k++) {
r1 = Init1 & B[k];
r2 = (B[k-1] | Next[A[k-1]|B[k-1]]) &r_NO_ERR;
A[k] = (Next[B[k]] & CMask) | r1 | r2;
}
if (DELIMITER) CurrentByteOffset += 1*D_length;
else CurrentByteOffset += 1*1;
}
Nextcharmem:
c = buffer[i];
CMask = RMask[c];
if(c != Newline)
{
r1 = Init1 & A[0];
B[0] = (Next[A[0]] & CMask) | r1;
r1 = Init1 & A[1];
B[1] = (Next[A[1]] & CMask) | ((A[0] | Next[A[0] | B[0]]) & r_NO_ERR) | r1 ;
if(D == 1) goto Nextchar1mem;
r1 = Init1 & A[2];
B[2] = (Next[A[2]] & CMask) | ((A[1] | Next[A[1] | B[1]]) &r_NO_ERR) | r1 ;
if(D == 2) goto Nextchar1mem;
r1 = Init1 & A[3];
B[3] = (Next[A[3]] & CMask) | ((A[2] | Next[A[2] | B[2]])&r_NO_ERR) | r1 ;
if(D == 3) goto Nextchar1mem;
r1 = Init1 & A[4];
B[4] = (Next[A[4]] & CMask) | ((A[3] | Next[A[3] | B[3]])&r_NO_ERR) | r1 ;
goto Nextchar1mem;
} /* if(NOT Newline) */
else {
j++;
if (DELIMITER) CurrentByteOffset -= D_length;
else CurrentByteOffset -= 1;
r1 = Init1 & A[D]; /* match endofline */
B[D] = (Next[A[D]] & CMask) | r1;
if(TAIL) B[D] = Next[B[D]] | B[D];
if((B[D] & 1) ^ INVERSE ) {
if(FILENAMEONLY && (NEW_FILE || !POST_FILTER)) {
num_of_matched++;
if (agrep_finalfp != NULL)
fprintf(agrep_finalfp, "%s\n", CurrentFileName);
else {
int outindex;
for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
(CurrentFileName[outindex] != '\0'); outindex++) {
agrep_outbuffer[agrep_outpointer+outindex] = CurrentFileName[outindex];
}
if ((CurrentFileName[outindex] != '\0') || (outindex+agrep_outpointer+1>=agrep_outlen)) {
OUTPUT_OVERFLOW;
free_buf(Text, buffer);
return -1;
}
else agrep_outbuffer[agrep_outpointer+outindex++] = '\n';
agrep_outpointer += outindex;
}
free_buf(Text, buffer);
NEW_FILE = OFF;
return 0;
}
if (-1 == r_output(buffer, i, end, j)) {free_buf(Text, buffer); return -1;}
if (((LIMITOUTPUT > 0) && (LIMITOUTPUT <= num_of_matched)) ||
((LIMITPERFILE > 0) && (LIMITPERFILE <= num_of_matched - prev_num_of_matched))) {
free_buf(Text, buffer);
return 0; /* done */
}
}
for(k=0; k<= D; k++) {
A[k] = B[k] = Init[k];
}
r1 = Init1 & A[0];
B[0] = (Next[A[0]] & CMask) | r1;
for(k=1; k<= D; k++) {
r1 = Init1 & A[k];
r2 = (A[k-1] | Next[A[k-1]|B[k-1]])&r_NO_ERR;
B[k] = (Next[A[k]] & CMask) | r1 | r2;
}
if (DELIMITER) CurrentByteOffset += 1*D_length;
else CurrentByteOffset += 1*1;
}
Nextchar1mem:
i++;
CurrentByteOffset ++;
} /* while i < end */
return 0;
}
#endif /*AGREP_POINTER*/
} /* re */
int
r_output (buffer, i, end, j)
int i, end, j;
CHAR *buffer;
{
int PRINTED = 0;
int bp;
if(i >= end) return 0;
if ((j < 1) || (CurrentByteOffset < 0)) return 0;
num_of_matched++;
if(COUNT) return 0;
if(FNAME && (NEW_FILE || !POST_FILTER)) {
char nextchar = (POST_FILTER == ON)?'\n':' ';
char *prevstring = (POST_FILTER == ON)?"\n":"";
if (agrep_finalfp != NULL)
fprintf(agrep_finalfp, "%s%s:%c", prevstring, CurrentFileName, nextchar);
else {
int outindex;
if (prevstring[0] != '\0') {
if(agrep_outpointer + 1 >= agrep_outlen) {
OUTPUT_OVERFLOW;
return -1;
}
else agrep_outbuffer[agrep_outpointer ++] = prevstring[0];
}
for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
(CurrentFileName[outindex] != '\0'); outindex++) {
agrep_outbuffer[agrep_outpointer+outindex] = CurrentFileName[outindex];
}
if ((CurrentFileName[outindex] != '\0') || (outindex+agrep_outpointer+2>=agrep_outlen)) {
OUTPUT_OVERFLOW;
return -1;
}
else {
agrep_outbuffer[agrep_outpointer+outindex++] = ':';
agrep_outbuffer[agrep_outpointer+outindex++] = nextchar;
}
agrep_outpointer += outindex;
}
NEW_FILE = OFF;
PRINTED = 1;
}
bp = i-1;
while ((buffer[bp] != '\n') && (bp > 0)) bp--;
if(LINENUM) {
if (agrep_finalfp != NULL)
fprintf(agrep_finalfp, "%d: ", j-1);
else {
char s[32];
int outindex;
sprintf(s, "%d: ", j-1);
for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
(s[outindex] != '\0'); outindex++) {
agrep_outbuffer[agrep_outpointer+outindex] = s[outindex];
}
if (s[outindex] != '\0') {
OUTPUT_OVERFLOW;
return -1;
}
agrep_outpointer += outindex;
}
PRINTED = 1;
}
if(BYTECOUNT) {
if (agrep_finalfp != NULL)
fprintf(agrep_finalfp, "%d= ", CurrentByteOffset);
else {
char s[32];
int outindex;
sprintf(s, "%d= ", CurrentByteOffset);
for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
(s[outindex] != '\0'); outindex++) {
agrep_outbuffer[agrep_outpointer+outindex] = s[outindex];
}
if (s[outindex] != '\0') {
OUTPUT_OVERFLOW;
return -1;
}
agrep_outpointer += outindex;
}
PRINTED = 1;
}
if(buffer[bp] != '\n') bp = Maxline-1;
bp++;
if (PRINTOFFSET) {
if (agrep_finalfp != NULL)
fprintf(agrep_finalfp, "@%d{%d} ", CurrentByteOffset - (i-bp), i-bp);
else {
char s[32];
int outindex;
sprintf(s, "@%d{%d} ", CurrentByteOffset - (i-bp), i-bp);
for (outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
(s[outindex] != '\0'); outindex ++) {
agrep_outbuffer[agrep_outpointer+outindex] = s[outindex];
}
if (s[outindex] != '\0') {
OUTPUT_OVERFLOW;
return -1;
}
agrep_outpointer += outindex;
}
PRINTED = 1;
}
if (PRINTRECORD) {
if (agrep_finalfp != NULL)
while(bp <= i) fputc(buffer[bp++], agrep_finalfp);
else {
if (i - bp + 1 + agrep_outpointer >= agrep_outlen) {
OUTPUT_OVERFLOW;
return -1;
}
while(bp <= i) agrep_outbuffer[agrep_outpointer ++] = buffer[bp++];
}
}
else if (PRINTED) {
if (agrep_finalfp != NULL) fputc('\n', agrep_finalfp);
else agrep_outbuffer[agrep_outpointer ++] = '\n';
PRINTED = 0;
}
return 0;
}
/*
* Processes the options specified in argc and argv, and fetches the pattern.
* Also sets the set of filenames to be searched for internally. Returns: -1
* if there is a serious error, 0 if there is no pattern or an error in getting
* the file names, the length (> 0) of the pattern if there is no error. When a
* 0 is returned, it means that at least the options were processed correctly.
*/
int
agrep_init(argc, argv, initialfd, pattern_len, pattern_buffer)
int argc;
char *argv[];
int initialfd;
int pattern_len;
CHAR *pattern_buffer;
{
int i, j, seenlsq = 0;
char c, *p;
int filetype;
char **original_argv = argv;
char *home;
int quitwhile;
int NOOUTTAIL=OFF;
initial_value();
if (pattern_len < 1) {
fprintf(stderr, "agrep_init: pattern length %d too small\n", pattern_len);
errno = 3;
return -1;
}
agrep_initialfd = initialfd;
strncpy(Progname, argv[0], MAXNAME);
if (argc < 2) return agrep_usage();
Pattern[0] = '\0';
while(--argc > 0 && (*++argv)[0] == '-') { /* argv is incremented automatically here */
p = argv[0]+1; /* ptr to first character after '-' */
c = *(argv[0]+1);
quitwhile = OFF;
while(!quitwhile && (*p != '\0')) {
c = *p;
switch(c) {
case 'z' :
NOOUTPUTZERO = ON; /* don't output files with 0 matches */
PRINT(printf("z\n");
)
break;
case 'c' :
COUNT = ON; /* output the # of matches */
PRINT(printf("c\n");
)
break;
case 's' :
SILENT = ON; /* silent mode */
PRINT(printf("s\n");
)
break;
case 'p' :
I = 0; /* insertion cost is 0 */
PRINT(printf("p\n");
)
break;
case 'P' :
PRINTPATTERN = 1; /* print pattern before every matched line */
PRINT(printf("p\n");
)
break;
case 'x' :
WHOLELINE = ON; /* match the whole line */
PRINT(printf("x\n");
)
if(WORDBOUND) {
fprintf(stderr, "%s: illegal option combination (-x and -w)\n", Progname);
if (!EXITONERROR) {
errno = AGREP_ERROR;
return -1;
}
else exit(2);
}
break;
case 'b' :
BYTECOUNT = ON;
PRINT(printf("b\n");
)
break;
case 'q' :
PRINTOFFSET = ON;
PRINT(printf("b\n");
)
break;
case 'u' :
PRINTRECORD = OFF;
PRINT(printf("u\n");
)
break;
case 'g' :
PRINTFILENUMBER = ON;
PRINT(printf("u\n");
)
break;
case 'L' :
if ( *(p + 1) == '\0') {/* space after -L option */
if(argc <= 1) {
fprintf(stderr, "%s: the -L option must have an output-limit argument\n", Progname);
if (!EXITONERROR) {
errno = AGREP_ERROR;
return -1;
}
else exit(2);
}
argv++;
LIMITOUTPUT = LIMITTOTALFILE = LIMITPERFILE = 0;
sscanf(argv[0], "%d:%d:%d", &LIMITOUTPUT, &LIMITTOTALFILE, &LIMITPERFILE);
if ((LIMITOUTPUT < 0) || (LIMITTOTALFILE < 0) || (LIMITPERFILE < 0)) {
fprintf(stderr, "%s: invalid output limit %s\n", Progname, argv[0]);
if (!EXITONERROR) {
errno = AGREP_ERROR;
return -1;
}
else exit(2);
}
argc--;
}
else {
LIMITOUTPUT = LIMITTOTALFILE = LIMITPERFILE = 0;
sscanf(p+1, "%d:%d:%d", &LIMITOUTPUT, &LIMITTOTALFILE, &LIMITPERFILE);
if ((LIMITOUTPUT < 0) || (LIMITTOTALFILE < 0) || (LIMITPERFILE < 0)) {
fprintf(stderr, "%s: invalid output limit %s\n", Progname, p+1);
if (!EXITONERROR) {
errno = AGREP_ERROR;
return -1;
}
else exit(2);
}
} /* else */
PRINT(printf("L\n");
)
quitwhile = ON;
break;
case 'd' :
DELIMITER = ON; /* user defines delimiter */
PRINT(printf("d\n");
)
if ( *(p + 1) == '\0') {/* space after -d option */
if(argc <= 1) {
fprintf(stderr, "%s: the -d option must have a delimiter argument\n", Progname);
if (!EXITONERROR) {
errno = AGREP_ERROR;
return -1;
}
else exit(2);
}
argv++;
if ((D_length = strlen(argv[0])) > MaxDelimit) {
fprintf(stderr, "%s: delimiter pattern too long (has > %d chars)\n", Progname, MaxDelimit);
if (!EXITONERROR) {
errno = AGREP_ERROR;
return -1;
}
else exit(2);
}
D_pattern[0] = '<';
strcpy(D_pattern+1, argv[0]);
if (((argv[0][D_length-1] == '\n') || (argv[0][D_length-1] == '$') || (argv[0][D_length-1] == '^')) && (D_length == 1))
OUTTAIL = ON;
argc--;
PRINT(printf("space\n");
)
}
else {
if ((D_length = strlen(p + 1)) > MaxDelimit) {
fprintf(stderr, "%s: delimiter pattern too long (has > %d chars)\n", Progname, MaxDelimit);
if (!EXITONERROR) {
errno = AGREP_ERROR;
return -1;
}
else exit(2);
}
D_pattern[0] = '<';
strcpy(D_pattern+1, p + 1);
if ((((p+1)[D_length-1] == '\n') || ((p+1)[D_length-1] == '$') || ((p+1)[D_length-1] == '^')) && (D_length == 1))
OUTTAIL = ON;
} /* else */
strcat(D_pattern, ">; ");
D_length++; /* to count '<' as one */
PRINT(printf("D_pattern=%s\n", D_pattern);
)
strcpy(original_D_pattern, D_pattern);
original_D_length = D_length;
quitwhile = ON;
break;
case 'H':
if (*(p + 1) == '\0') {/* space after - option */
if (argc <= 1) {
fprintf(stderr, "%s: a directory name must follow the -H option\n", Progname);
if (!EXITONERROR) {
errno = AGREP_ERROR;
return agrep_usage();
}
else exit(2);
}
argv ++;
strcpy(COMP_DIR, argv[0]);
argc --;
}
else {
strcpy(COMP_DIR, p+1);
}
quitwhile = ON;
break;
case 'e' :
if ( *(p + 1) == '\0') {/* space after -e option */
if(argc <= 1) {
fprintf(stderr, "%s: the -e option must have a pattern argument\n", Progname);
if (!EXITONERROR) {
errno = AGREP_ERROR;
return -1;
}
else exit(2);
}
argv++;
if(argv[0][0] == '-') { /* not strictly necessary but no harm done */
Pattern[0] = '\\';
strcat(Pattern, (argv)[0]);
}
else strcat(Pattern, argv[0]);
argc--;
}
else {
if (*(p+1) == '-') { /* not strictly necessary but no harm done */
Pattern[0] = '\\';
strcat(Pattern, p+1);
}
else strcat (Pattern, p+1);
} /* else */
PRINT(printf("Pattern=%s\n", Pattern);
)
pattern_index = abs(argv - original_argv);
quitwhile = ON;
break;
case 'k' :
CONSTANT = ON;
if ( *(p + 1) == '\0') {/* space after -e option */
if(argc <= 1) {
fprintf(stderr, "%s: the -k option must have a pattern argument\n", Progname);
if (!EXITONERROR) {
errno = AGREP_ERROR;
return -1;
}
else exit(2);
}
argv++;
strcat(Pattern, argv[0]);
if((argc > 2) && (argv[1][0] == '-')) {
fprintf(stderr, "%s: -k should be the last option in the command\n", Progname);
if (!EXITONERROR) {
errno = AGREP_ERROR;
return -1;
}
else exit(2);
}
argc--;
}
else {
if((argc > 1) && (argv[1][0] == '-')) {
fprintf(stderr, "%s: -k should be the last option in the command\n", Progname);
if (!EXITONERROR) {
errno = AGREP_ERROR;
return -1;
}
else exit(2);
}
strcat (Pattern, p+1);
} /* else */
pattern_index = abs(argv - original_argv);
quitwhile = ON;
break;
case 'f' :
if (PAT_FILE == ON) {
fprintf(stderr, "%s: multiple -f options\n", Progname);
if (multifd >= 0) close(multifd);
if (!EXITONERROR) {
errno = AGREP_ERROR;
return -1;
}
else exit(2);
}
if (PAT_BUFFER == ON) {
fprintf(stderr, "%s: -f and -m are incompatible\n", Progname);
if (multibuf != NULL) free(multibuf);
multibuf = NULL;
multilen = 0;
if (!EXITONERROR) {
errno = AGREP_ERROR;
return -1;
}
else exit(2);
}
PAT_FILE = ON;
PRINT(printf("f\n");
)
argv++;
argc--;
if (argv[0] == NULL) {
/* A -f option with a NULL file name is a NO-OP: stupid, but simplifies glimpse :-) */
PAT_FILE = OFF;
quitwhile = ON;
break;
}
if((multifd = open(argv[0], O_RDONLY)) < 0) {
PAT_FILE = OFF;
fprintf(stderr, "%s: can't open pattern file for reading: %s\n", Progname, argv[0]);
if (!EXITONERROR) {
errno = AGREP_ERROR;
return -1;
}
else exit(2);
}
PRINT(printf("file=%s\n", argv[0]);
)
strcpy(PAT_FILE_NAME, argv[0]);
if (prepf(multifd, NULL, 0) <= -1) {
close(multifd);
PAT_FILE = OFF;
fprintf(stderr, "%s: error in processing pattern file: %s\n", Progname, argv[0]);
if (!EXITONERROR) {
errno = AGREP_ERROR;
return -1;
}
else exit(2);
}
quitwhile = ON;
break;
case 'm' :
if (PAT_BUFFER == ON) {
fprintf(stderr, "%s: multiple -m options\n", Progname);
if (multibuf != NULL) free(multibuf);
multilen = 0;
if (!EXITONERROR) {
errno = AGREP_ERROR;
return -1;
}
else exit(2);
}
if (PAT_FILE == ON) {
fprintf(stderr, "%s: -f and -m are incompatible\n", Progname);
if (multifd >= 0) close(multifd);
if (!EXITONERROR) {
errno = AGREP_ERROR;
return -1;
}
else exit(2);
}
PAT_BUFFER = ON;
PRINT(printf("m\n");
)
argv ++;
argc --;
if ((argv[0] == NULL) || ((multilen = strlen(argv[0])) <= 0)) {
/* A -m option with a NULL or empty pattern buffer is a NO-OP: stupid, but simplifies glimpse :-) */
PAT_BUFFER = OFF;
multilen = 0;
multibuf = NULL;
}
else {
multibuf = (char *)malloc(multilen + 2);
strcpy(multibuf, argv[0]);
PRINT(printf("patterns=%s\n", multibuf);
)
if (prepf(-1, multibuf, multilen) <= -1) {
free(multibuf);
multilen = 0;
PAT_BUFFER = OFF;
fprintf(stderr, "%s: error in processing pattern buffer\n", Progname);
if (!EXITONERROR) {
errno = AGREP_ERROR;
return -1;
}
else exit(2);
}
}
quitwhile = ON;
break;
case 'h' :
NOFILENAME = ON;
PRINT(printf("h\n");
)
break;
case 'i' :
NOUPPER = ON;
PRINT(printf("i\n");
)
break;
case 'l' :
FILENAMEONLY = ON;
PRINT(printf("l\n");
)
break;
case 'n' :
LINENUM = ON; /* output prefixed by line no*/
PRINT(printf("n\n");
)
break;
case 'r' :
RECURSIVE = ON;
PRINT(printf("r\n");
)
break;
case 'V' :
printf("\nThis is agrep version %s, %s.\n\n", AGREP_VERSION, AGREP_DATE);
return 0;
case 'v' :
INVERSE = ON; /* output no-matched lines */
PRINT(printf("v\n");
)
break;
case 't' :
OUTTAIL = ON; /* output from tail of delimiter */
PRINT(printf("t\n");
)
break;
case 'o' :
NOOUTTAIL = ON; /* output from front of delimiter */
PRINT(printf("t\n");
)
break;
case 'B' :
BESTMATCH = ON;
PRINT(printf("B\n");
)
break;
case 'w' :
WORDBOUND = ON;/* match to words */
PRINT(printf("w\n");
)
if(WHOLELINE) {
fprintf(stderr, "%s: illegal option combination (-w and -x)\n", Progname);
if (!EXITONERROR) {
errno = AGREP_ERROR;
return -1;
}
else exit(2);
}
break;
case 'y' :
NOPROMPT = ON;
PRINT(printf("y\n");
)
break;
case 'I' :
I = atoi(p + 1); /* Insertion Cost */
JUMP = ON;
quitwhile = ON;
break;
case 'S' :
S = atoi(p + 1); /* Substitution Cost */
JUMP = ON;
quitwhile = ON;
break;
case 'D' :
DD = atoi(p + 1); /* Deletion Cost */
JUMP = ON;
quitwhile = ON;
break;
case 'G' :
FILEOUT = ON;
COUNT = ON;
break;
case 'A':
ALWAYSFILENAME = ON;
break;
case 'O':
POST_FILTER = ON;
case 'M':
MULTI_OUTPUT = ON;
case 'Z': break; /* no-op: used by glimpse */
default :
if (isdigit(c)) {
APPROX = ON;
D = atoi(p);
if (D > MaxError) {
fprintf(stderr,"%s: the maximum number of errors is %d\n", Progname, MaxError);
if (!EXITONERROR) {
errno = AGREP_ERROR;
return -1;
}
else exit(2);
}
quitwhile = ON; /* note that even a number should occur at the end of a group of options, as f & e */
}
else {
fprintf(stderr, "%s: illegal option -%c\n",Progname, c);
return agrep_usage();
}
} /* switch(c) */
p ++;
}
} /* while (--argc > 0 && (*++argv)[0] == '-') */
if (NOOUTTAIL == ON) OUTTAIL = OFF;
if (COMP_DIR[0] == '\0') {
if ((home = (char *)getenv("HOME")) == NULL) {
getcwd(COMP_DIR, MAX_LINE_LEN-1);
fprintf(stderr, "using working-directory '%s' to locate dictionaries\n", COMP_DIR);
}
else strncpy(COMP_DIR, home, MAX_LINE_LEN);
}
strcpy(FREQ_FILE, COMP_DIR);
strcat(FREQ_FILE, "/");
strcat(FREQ_FILE, DEF_FREQ_FILE);
strcpy(HASH_FILE, COMP_DIR);
strcat(HASH_FILE, "/");
strcat(HASH_FILE, DEF_HASH_FILE);
strcpy(STRING_FILE, COMP_DIR);
strcat(STRING_FILE, "/");
strcat(STRING_FILE, DEF_STRING_FILE);
initialize_common(FREQ_FILE, 0); /* no error msgs */
if (FILENAMEONLY && NOFILENAME) {
fprintf(stderr, "%s: -h and -l options are mutually exclusive\n",Progname);
}
if (COUNT && (FILENAMEONLY || NOFILENAME)) {
FILENAMEONLY = OFF;
if(!FILEOUT) NOFILENAME = OFF;
}
if (!(PAT_FILE || PAT_BUFFER) && Pattern[0] == '\0') { /* Pattern not set with -e option */
if (argc <= 0) {
agrep_usage();
return 0;
}
strcpy(Pattern, *argv);
pattern_index = abs(argv - original_argv);
argc--;
argv++;
}
/* if multi-pattern search, just ignore any specified pattern altogether: treat it as a filename */
if (copied_from_argv) {
for (i=0; i<Numfiles; i++) free(Textfiles[i]);
if (Textfiles != NULL) free(Textfiles);
}
copied_from_argv = 0;
Numfiles = 0; Textfiles = NULL;
execfd = agrep_initialfd;
if (argc <= 0) /* check Pattern against stdin */
execfd = 0;
else { /* filenames were specified as a part of the command line */
if (!(Textfiles = (CHAR **)malloc(argc * sizeof(CHAR *) ))) {
fprintf(stderr, "%s: malloc failure in %s:%d\n", Progname, __FILE__, __LINE__);
if (!EXITONERROR) {
errno = AGREP_ERROR;
return 0;
}
else exit(2);
}
copied_from_argv = 1; /* should I free Textfiles next time? */
while (argc--)
{ /* one or more filenames on command line -- put the valid filenames in a array of strings */
if ((filetype = check_file(*argv)) == NOSUCHFILE) {
if (!glimpse_call) if (!glimpse_call) fprintf(stderr,"%s: '%s' no such file or directory\n",Progname,*argv);
argv++;
}
else { /* file is ascii*/
if (!(Textfiles[Numfiles] = (CHAR *)malloc((strlen(*argv)+2)))) {
fprintf(stderr, "%s: malloc failure in %s:%d\n", Progname, __FILE__, __LINE__);
if (!EXITONERROR) {
errno = AGREP_ERROR;
return 0;
}
else exit(2);
}
strcpy(Textfiles[Numfiles++], *argv++);
} /* else */
} /* while (argc--) */
if (Numfiles <= 0) return 0;
/* If user specified wrong filenames, then we quit rather than taking input from stdin! */
} /* else */
M = strlen(Pattern);
if (M<=0) return 0;
for (i=0; i<M; i++) {
if (( ((unsigned char *)Pattern)[i] > USERRANGE_MIN) && ( ((unsigned char *)Pattern)[i] <= USERRANGE_MAX)) {
fprintf(stderr, "Warning: pattern has some meta-characters interpreted by agrep!\n");
break;
}
else if (Pattern[i] == '\\') i++; /* extra */
else if (Pattern[i] == '[') seenlsq = 1;
else if ((Pattern[i] == '-') && !seenlsq) {
for (j=M; j>=i; j--)
Pattern[j+1] = Pattern[j]; /* right shift including '\0' */
Pattern[i] = '\\'; /* escape the - */
M ++;
i++;
}
else if (Pattern[i] == ']') seenlsq = 0;
}
if (M > pattern_len - 1) {
fprintf(stderr, "%s: pattern '%s' does not fit in specified buffer\n", Progname, Pattern);
errno = 3;
return 0;
}
if (pattern_buffer != Pattern) /* not from mem/file-agrep() */
strncpy(pattern_buffer, Pattern, M+1); /* copy \0 */
return M;
}
/*
* User need not bother about initialfd.
* Both functions return -1 on error, 0 if there was no pattern,
* length (>=1) of pattern otherwise.
*/
int
memagrep_init(argc, argv, pattern_len, pattern_buffer)
int argc;
char *argv[];
int pattern_len;
char *pattern_buffer;
{
return (agrep_init(argc, argv, -1, pattern_len, pattern_buffer));
}
int
fileagrep_init(argc, argv, pattern_len, pattern_buffer)
int argc;
char *argv[];
int pattern_len;
char *pattern_buffer;
{
return (agrep_init(argc, argv, 3, pattern_len, pattern_buffer));
}
/* returns -1 on error, num of matches (>=0) otherwise */
int
agrep_search(pattern_len, pattern_buffer, initialfd, input_len, input, output_len, output)
int pattern_len;
CHAR *pattern_buffer;
int initialfd;
int input_len;
void *input;
int output_len;
void *output;
{
int i;
int filetype;
int ret;
int pattern_has_changed = 1;
if ((multifd == -1) && (multibuf == NULL) && (pattern_len < 1)) {
fprintf(stderr, "%s: pattern length %d too small\n", Progname, pattern_len);
errno = 3;
return -1;
}
if (pattern_len >= MAXPAT) {
fprintf(stderr, "%s: pattern '%s' too long\n", Progname, pattern_buffer);
errno = 3;
return -1;
}
/* courtesy: crd@hplb.hpl.hp.com */
if (agrep_saved_pattern) {
if (strcmp(agrep_saved_pattern, pattern_buffer)) {
free(agrep_saved_pattern);
agrep_saved_pattern = NULL;
}
else {
pattern_has_changed = 0;
}
}
if (! agrep_saved_pattern) {
agrep_saved_pattern = (CHAR *)malloc(pattern_len+1);
memcpy(agrep_saved_pattern, pattern_buffer, pattern_len);
agrep_saved_pattern[pattern_len] = '\0';
}
if (!pattern_has_changed) {
reinit_value_partial();
}
else {
reinit_value();
if (pattern_buffer != Pattern) /* not from mem/file-agrep() */
strncpy(Pattern, pattern_buffer, pattern_len+1); /* copy \0 */
M = strlen(Pattern);
}
if (output == NULL) {
fprintf(stderr, "%s: invalid output descriptor\n", Progname);
return -1;
}
if (output_len <= 0) {
agrep_finalfp = (FILE *)output;
agrep_outlen = 0;
agrep_outbuffer = NULL;
agrep_outpointer = 0;
}
else {
agrep_finalfp = NULL;
agrep_outlen = output_len;
agrep_outbuffer = (CHAR *)output;
agrep_outpointer = 0;
}
agrep_initialfd = initialfd;
execfd = initialfd;
if (initialfd == -1) {
agrep_inbuffer = (CHAR *)input;
agrep_inlen = input_len;
agrep_inpointer = 0;
}
else if ((input_len > 0) && (input != NULL)) {
/* Copy the set of filenames into Textfiles */
if (copied_from_argv) {
for (i=0; i<Numfiles; i++) free(Textfiles[i]);
if (Textfiles != NULL) free(Textfiles);
}
copied_from_argv = 0;
Numfiles = 0; Textfiles = NULL;
#if 0
if (!(Textfiles = (CHAR **)malloc(input_len * sizeof(CHAR *) ))) {
fprintf(stderr, "%s: malloc failure in %s:%d\n", Progname, __FILE__, __LINE__);
if (!EXITONERROR) {
errno = AGREP_ERROR;
return 0;
}
else exit(2);
}
#else /*0*/
Textfiles = (CHAR **)input;
#endif /*0*/
while (input_len --)
{ /* one or more filenames on command line -- put the valid filenames in a array of strings */
if ((filetype = check_file(*(char **)input)) == NOSUCHFILE) {
if(filetype == NOSUCHFILE) if (!glimpse_call) fprintf(stderr,"%s: '%s' no such file or directory\n",Progname,*(char **)input);
input = (void *)(((long)input) + sizeof(char *));
}
else { /* file is ascii*/
#if 0
if (!(Textfiles[Numfiles] = (CHAR *)malloc((strlen(*(char **)input)+2)))) {
fprintf(stderr, "%s: malloc failure in %s:%d\n", Progname, __FILE__, __LINE__);
if (!EXITONERROR) {
errno = AGREP_ERROR;
return 0;
}
else exit(2);
}
strcpy(Textfiles[Numfiles++], *((char **)input));
#else /*0*/
Textfiles[Numfiles++] = *((CHAR **)input);
#endif /*0*/
input = (void *)(((long)input) + sizeof(char *));
} /* else */
} /* while (argc--) */
if (Numfiles <= 0) return 0;
/* If user specified wrong filenames, then we quit rather than taking input from stdin! */
}
else if (Numfiles <= 0) execfd = 0;
/* the old set of files (agrep_init) are used */
#if 0
printf("agrep_search: pat=%s buf=%s\n", Pattern, ((agrep_initialfd == -1) && (agrep_inlen < 20)) ? agrep_inbuffer : NULL);
#endif /*0*/
if (pattern_has_changed) {
if (-1 == checksg(Pattern, D, 1)) return -1; /* check if the pattern is simple */
strcpy(OldPattern, Pattern);
if (SGREP == 0) { /* complex pattern search */
if (-1 == preprocess(D_pattern, Pattern)) return -1;
strcpy(old_D_pat, D_pattern);
/* fprintf(stderr, "agrep_search: len=%d pat=%s\n", strlen(Pattern), Pattern); */
if(!AParse && ((M = maskgen(Pattern, D)) == -1)) return -1;
}
else { /* sgrep too can handle delimiters */
if (DELIMITER) {
/* D_pattern is "<PAT>; ", D_length is 1 + length of string PAT: see agrep.c/'d' */
preprocess_delimiter(D_pattern+1, D_length - 1, D_pattern, &D_length);
/* D_pattern is the exact stuff we want to match, D_length is its strlen */
if ((tc_D_length = quick_tcompress(FREQ_FILE,HASH_FILE,D_pattern,D_length,tc_D_pattern,MaxDelimit*2,TC_EASYSEARCH)) <= 0) {
strcpy(tc_D_pattern, D_pattern);
tc_D_length = D_length;
}
/* printf("sgrep's delim=%s,%d tc_delim=%s,%d\n", D_pattern, D_length, tc_D_pattern, tc_D_length); */
}
M = strlen(OldPattern);
}
}
if (AParse) { /* boolean converted to multi-pattern search */
int prepf_ret= 0;
if (pattern_has_changed)
prepf_ret= prepf(-1, multibuf, multilen);
if (prepf_ret <= -1) {
if (AComplexBoolean) destroy_tree(AParse);
AParse = 0;
PAT_BUFFER = 0;
if (multibuf != NULL) free(multibuf); /* this was allocated for arbit booleans, not multipattern search */
multilen = 0;
/* Cannot free multifd here since that is always allocated for multipattern search */
return -1;
}
}
if (Numfiles > 1) FNAME = ON;
if (NOFILENAME) FNAME = 0;
if (ALWAYSFILENAME) FNAME = ON; /* used by glimpse ONLY: 15/dec/93 */
if (agrep_initialfd == -1) ret = exec(execfd, NULL);
else if(RECURSIVE) ret = (recursive(Numfiles, Textfiles));
else ret = (exec(execfd, Textfiles));
return ret;
}
/*
* User need not bother about initialfd.
* Both functions return -1 on error, 0 otherwise.
*/
int
memagrep_search(pattern_len, pattern_buffer, input_len, input_buffer, output_len, output)
int pattern_len;
char *pattern_buffer;
int input_len;
char *input_buffer;
int output_len;
void *output;
{
return(agrep_search(pattern_len, pattern_buffer, -1, input_len, input_buffer, output_len, output));
}
int
fileagrep_search(pattern_len, pattern_buffer, file_num, file_buffer, output_len, output)
int pattern_len;
char *pattern_buffer;
int file_num;
char **file_buffer;
int output_len;
void *output;
{
return(agrep_search(pattern_len, pattern_buffer, 3, file_num, file_buffer, output_len, output));
}
/*
* The original agrep_run() routine was split into agrep_search and agrep_init
* so that the interface with glimpse could be made cleaner: see glimpse.
* Now, the user can specify an initial set of options, and use them in future
* searches. If agrep_init does not find the pattern, options are still SET.
* In fileagrep_search, the user can specify a NEW set of files to be searched
* after the options are processed (this is used in glimpse).
*
* Both functions return -1 on error, 0 otherwise.
*
* The arguments are self explanatory. The pattern should be specified in
* one of the argvs. Options too can be specified in one of the argvs -- it
* is exactly as if the options are being given to agrep at run time.
* The only restrictions are that the input_buffer should begin with a '\n'
* and after its end, there must be valid memory to store a copy of the pattern.
*/
int
memagrep(argc, argv, input_len, input_buffer, output_len, output)
int argc;
char *argv[];
int input_len;
char *input_buffer;
int output_len;
void *output;
{
int ret;
if ((ret = memagrep_init(argc, argv, MAXPAT, Pattern)) < 0) return -1;
else if ((ret == 0) && (multifd == -1) && (multibuf == NULL)) return -1;
/* ^^^ because one need not specify the pattern on the cmd line if -f OR -m */
return memagrep_search(ret, Pattern, input_len, input_buffer, output_len, output);
}
int
fileagrep(argc, argv, output_len, output)
int argc;
char *argv[];
int output_len;
void *output;
{
int ret;
if ((ret = fileagrep_init(argc, argv, MAXPAT, Pattern)) < 0) return -1;
else if ((ret == 0) && (multifd == -1) && (multibuf == NULL)) return -1;
/* ^^^ because one need not specify the pattern on the cmd line if -f OR -m */
return fileagrep_search(ret, Pattern, 0, NULL, output_len, output);
}
/*
* RETURNS: total number of matched lines in all files that were searched.
*
* The pattern(s) remain(s) constant irrespective of the number of files.
* Hence, essentially, all the interface routines below have to be changed
* so that they DONT do that preprocessing again and again for multiple
* files. This bug was found while interfacing agrep with cast.
*
* At present, sgrep() has been modified to have another parameter,
* "samepattern" that tells it whether the pattern is the same as before.
* Other funtions too should have such a parameter and should not repeat
* preprocessing for all patterns. Since preprocessing for a pattern to
* be searched in compressed files is siginificant, this bug was found.
*
* - bgopal on 15/Nov/93.
*/
int
exec(fd, file_list)
int fd;
char **file_list;
{
int i;
char c[8];
int ret = 0; /* no error */
if ((Numfiles > 1) && (NOFILENAME == OFF)) FNAME = ON;
if ((-1 == compat())) return -1; /* check compatibility between options */
if (fd <= 0) {
TCOMPRESSED = ON; /* there is a possibility that the data might be tuncompressible */
if (!SetCurrentByteOffset) CurrentByteOffset = 0;
if((fd == 0) && FILENAMEONLY) {
fprintf(stderr, "%s: -l option is not compatible with standard input\n", Progname);
if (!EXITONERROR) {
errno = AGREP_ERROR;
return -1;
}
else exit(2);
}
if(PAT_FILE || PAT_BUFFER) mgrep(fd, AParse);
else {
if(SGREP) ret = sgrep(OldPattern, strlen(OldPattern), fd, D, 0);
else ret = bitap(old_D_pat, Pattern, fd, M, D);
}
if (ret <= -1) return -1;
if (COUNT && ret) { /* dirty solution for glimpse's -b! */
if(INVERSE && (PAT_FILE || PAT_BUFFER)) { /* inverse will never be set in glimpse */
if (agrep_finalfp != NULL)
fprintf(agrep_finalfp, "%d\n", total_line-(num_of_matched - prev_num_of_matched));
else {
char s[32];
int outindex;
sprintf(s, "%d\n", total_line-(num_of_matched - prev_num_of_matched));
for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
(s[outindex] != '\0'); outindex++) {
agrep_outbuffer[agrep_outpointer+outindex] = s[outindex];
}
if (s[outindex] != '\0') {
OUTPUT_OVERFLOW;
return -1;
}
agrep_outpointer += outindex;
}
}
else {
if (agrep_finalfp != NULL)
fprintf(agrep_finalfp, "%d\n", (num_of_matched - prev_num_of_matched));
else {
char s[32];
int outindex;
sprintf(s, "%d\n", (num_of_matched - prev_num_of_matched));
for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
(s[outindex] != '\0'); outindex++) {
agrep_outbuffer[agrep_outpointer+outindex] = s[outindex];
}
if (s[outindex] != '\0') {
OUTPUT_OVERFLOW;
return -1;
}
agrep_outpointer += outindex;
}
}
}
}
else {
/* fd > 0 => Numfiles > 0 */
for (i = 0; i < Numfiles; i++, close(fd)) {
prev_num_of_matched = num_of_matched;
if (!SetCurrentByteOffset) CurrentByteOffset = 0;
if (!SetCurrentFileName) {
if (PRINTFILENUMBER) sprintf(CurrentFileName, "%d", i);
else strcpy(CurrentFileName, file_list[i]);
}
TCOMPRESSED = ON;
if (!tuncompressible_filename(file_list[i], strlen(file_list[i]))) TCOMPRESSED = OFF;
NEW_FILE = ON;
if ((fd = open(file_list[i], O_RDONLY)) < /*=*/ 0) {
fprintf(stderr, "%s: can't open file for reading: %s\n",Progname, file_list[i]);
}
else {
if(PAT_FILE || PAT_BUFFER) mgrep(fd, AParse);
else {
if(SGREP) ret = sgrep(OldPattern, strlen(OldPattern), fd, D, i);
else ret = bitap(old_D_pat, Pattern, fd, M, D);
}
if (ret <= -1) {
close(fd);
return -1;
}
if (num_of_matched - prev_num_of_matched > 0) {
NOMATCH = OFF;
files_matched ++;
}
if (COUNT && !FILEOUT) {
if( (INVERSE && (PAT_FILE || PAT_BUFFER)) && ((total_line - (num_of_matched - prev_num_of_matched)> 0) || !NOOUTPUTZERO) ) {
if(FNAME && (NEW_FILE || !POST_FILTER)) {
if (agrep_finalfp != NULL)
fprintf(agrep_finalfp, "%s: %d\n", CurrentFileName, total_line - (num_of_matched - prev_num_of_matched));
else {
char s[32];
int outindex;
sprintf(s, ": %d\n", total_line - (num_of_matched - prev_num_of_matched));
for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
(CurrentFileName[outindex] != '\0'); outindex++) {
agrep_outbuffer[agrep_outpointer+outindex] = CurrentFileName[outindex];
}
if (CurrentFileName[outindex] != '\0') {
OUTPUT_OVERFLOW;
close(fd);
return -1;
}
agrep_outpointer += outindex;
for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
(s[outindex] != '\0'); outindex++) {
agrep_outbuffer[agrep_outpointer+outindex] = s[outindex];
}
if (s[outindex] != '\0') {
OUTPUT_OVERFLOW;
close(fd);
return -1;
}
agrep_outpointer += outindex;
}
NEW_FILE = OFF;
}
else if (!FNAME) {
if (agrep_finalfp != NULL)
fprintf(agrep_finalfp, "%d\n", total_line - (num_of_matched - prev_num_of_matched));
else {
char s[32];
int outindex;
sprintf(s, "%d\n", total_line - (num_of_matched - prev_num_of_matched));
for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
(s[outindex] != '\0'); outindex++) {
agrep_outbuffer[agrep_outpointer+outindex] = s[outindex];
}
if (s[outindex] != '\0') {
OUTPUT_OVERFLOW;
close(fd);
return -1;
}
agrep_outpointer += outindex;
}
}
}
else if ( !(INVERSE && (PAT_FILE || PAT_BUFFER)) && (((num_of_matched - prev_num_of_matched) > 0) || !NOOUTPUTZERO) ) {
/* inverse is always 0 in glimpse, so we always come here */
if(FNAME && (NEW_FILE || !POST_FILTER)) {
if (agrep_finalfp != NULL)
fprintf(agrep_finalfp, "%s: %d\n", CurrentFileName, (num_of_matched - prev_num_of_matched));
else {
char s[32];
int outindex;
sprintf(s, ": %d\n", (num_of_matched - prev_num_of_matched));
for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
(CurrentFileName[outindex] != '\0'); outindex++) {
agrep_outbuffer[agrep_outpointer+outindex] = CurrentFileName[outindex];
}
if (CurrentFileName[outindex] != '\0') {
OUTPUT_OVERFLOW;
close(fd);
return -1;
}
agrep_outpointer += outindex;
for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
(s[outindex] != '\0'); outindex++) {
agrep_outbuffer[agrep_outpointer+outindex] = s[outindex];
}
if (s[outindex] != '\0') {
OUTPUT_OVERFLOW;
close(fd);
return -1;
}
agrep_outpointer += outindex;
}
NEW_FILE = OFF;
}
else if (!FNAME) {
if (agrep_finalfp != NULL)
fprintf(agrep_finalfp, "%d\n", (num_of_matched - prev_num_of_matched));
else {
char s[32];
int outindex;
sprintf(s, "%d\n", (num_of_matched - prev_num_of_matched));
for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
(s[outindex] != '\0'); outindex++) {
agrep_outbuffer[agrep_outpointer+outindex] = s[outindex];
}
if (s[outindex] != '\0') {
OUTPUT_OVERFLOW;
close(fd);
return -1;
}
agrep_outpointer += outindex;
}
}
}
} /* if COUNT */
if(FILEOUT && (num_of_matched - prev_num_of_matched)) {
if (-1 == file_out(file_list[i])) {
close(fd);
return -1;
}
}
} /* else */
if (glimpse_clientdied) {
close(fd);
return -1;
}
if (agrep_finalfp != NULL) fflush(agrep_finalfp);
if (((LIMITOUTPUT > 0) && (LIMITOUTPUT <= num_of_matched)) ||
((LIMITTOTALFILE > 0) && (LIMITTOTALFILE <= files_matched))) {
close(fd);
break; /* done */
}
} /* for i < Numfiles */
if(NOMATCH && BESTMATCH) {
if(WORDBOUND || WHOLELINE || LINENUM || INVERSE) {
SGREP = 0;
if(-1 == preprocess(D_pattern, Pattern)) return -1;
strcpy(old_D_pat, D_pattern);
if((M = maskgen(Pattern, D)) == -1) return -1;
}
COUNT=ON;
D=1;
while(D<M && D<=MaxError && (num_of_matched - prev_num_of_matched == 0)) {
for (i = 0; i < Numfiles; i++, close(fd)) {
prev_num_of_matched = num_of_matched;
CurrentByteOffset = 0;
if (PRINTFILENUMBER) sprintf(CurrentFileName, "%d", i);
else strcpy(CurrentFileName, file_list[i]);
NEW_FILE = ON;
if ((fd = open(Textfiles[i], O_RDONLY)) > 0) {
if(PAT_FILE || PAT_BUFFER) mgrep(fd, AParse);
else {
if(SGREP) ret = sgrep(OldPattern,strlen(OldPattern),fd,D, i);
else ret = bitap(old_D_pat,Pattern,fd,M,D);
}
if (ret <= -1) return -1;
}
if (glimpse_clientdied) {
close(fd);
return -1;
}
if (agrep_finalfp != NULL) fflush(agrep_finalfp);
if ((((LIMITOUTPUT > 0) && (LIMITOUTPUT <= num_of_matched)) ||
((LIMITTOTALFILE > 0) && (LIMITTOTALFILE <= files_matched))) &&
(num_of_matched > prev_num_of_matched)) {
close(fd);
break;
}
} /* for i < Numfiles */
D++;
} /* while */
if(num_of_matched - prev_num_of_matched > 0) {
D--;
errno = D; /* #of errors if proper return */
COUNT = 0;
if(num_of_matched - prev_num_of_matched == 1) fprintf(stderr,"%s: 1 word matches ", Progname);
else fprintf(stderr,"%s: %d words match ", Progname, num_of_matched - prev_num_of_matched);
if(D==1) fprintf(stderr, "within 1 error");
else fprintf(stderr, "within %d errors", D);
fflush(stderr);
if(NOPROMPT) fprintf(stderr, "\n");
else {
if(num_of_matched - prev_num_of_matched == 1) fprintf(stderr,"; search for it? (y/n)");
else fprintf(stderr,"; search for them? (y/n)");
c[0] = 'y';
if (!glimpse_isserver && (fgets(c, 4, stdin) == NULL)) goto CONT;
if(c[0] != 'y') goto CONT;
}
for (i = 0; i < Numfiles; i++, close(fd)) {
prev_num_of_matched = num_of_matched;
CurrentByteOffset = 0;
if (PRINTFILENUMBER) sprintf(CurrentFileName, "%d", i);
else strcpy(CurrentFileName, file_list[i]);
NEW_FILE = ON;
if ((fd = open(Textfiles[i], O_RDONLY)) > 0) {
if(PAT_FILE || PAT_BUFFER) mgrep(fd, AParse);
else {
if(SGREP) ret = sgrep(OldPattern,strlen(OldPattern),fd,D, i);
else ret = bitap(old_D_pat,Pattern,fd,M,D);
}
if (ret <= -1) {
close(fd);
return -1;
}
}
if (glimpse_clientdied) {
close(fd);
return -1;
}
if (agrep_finalfp != NULL) fflush(agrep_finalfp);
if (((LIMITOUTPUT > 0) && (LIMITOUTPUT <= num_of_matched)) ||
((LIMITTOTALFILE > 0) && (LIMITTOTALFILE <= files_matched))) {
close(fd);
break; /* done */
}
} /* for i < Numfiles */
NOMATCH = 0;
}
}
}
CONT:
if(EATFIRST) {
if (agrep_finalfp != NULL) fprintf(agrep_finalfp, "\n");
else if (agrep_outpointer >= agrep_outlen) {
OUTPUT_OVERFLOW;
return -1;
}
else agrep_outbuffer[agrep_outpointer++] = '\n';
EATFIRST = OFF;
}
if(num_of_matched - prev_num_of_matched > 0) NOMATCH = OFF;
/* if(NOMATCH) return(0); */
/*printf("exec=%d\n", num_of_matched);*/
return(num_of_matched);
} /* end of exec() */
/* Just output the contents of the file fname onto the std output */
int
file_out(fname)
char *fname;
{
int num_read;
int fd;
int i, len;
CHAR buf[SIZE+2];
if(FNAME) {
len = strlen(fname);
if (agrep_finalfp != NULL) {
fputc('\n', agrep_finalfp);
for(i=0; i< len; i++) fputc(':', agrep_finalfp);
fputc('\n', agrep_finalfp);
fprintf(agrep_finalfp, "%s\n", fname);
for(i=0; i< len; i++) fputc(':', agrep_finalfp);
fputc('\n', agrep_finalfp);
fflush(agrep_finalfp);
}
else {
if (1+len+1+len+1+len+1+agrep_outpointer >= agrep_outlen) {
OUTPUT_OVERFLOW;
return -1;
}
agrep_outbuffer[agrep_outpointer++] = '\n';
for (i=0; i<len; i++) agrep_outbuffer[agrep_outpointer++] = ':';
agrep_outbuffer[agrep_outpointer++] = '\n';
for (i=0; i<len; i++) agrep_outbuffer[agrep_outpointer++] = fname[i];
agrep_outbuffer[agrep_outpointer++] = '\n';
for (i=0; i<len; i++) agrep_outbuffer[agrep_outpointer++] = ':';
agrep_outbuffer[agrep_outpointer++] = '\n';
}
}
fd = open(fname, O_RDONLY);
if (agrep_finalfp != NULL) {
while((num_read = fill_buf(fd, buf, SIZE)) > 0)
write(1, buf, num_read);
if (glimpse_clientdied) {
close(fd);
return -1;
}
}
else {
if ((num_read = fill_buf(fd, agrep_outbuffer + agrep_outpointer, agrep_outlen - agrep_outpointer)) > 0)
agrep_outpointer += num_read;
}
close(fd);
return 0;
}
int
output(buffer, i1, i2, j)
register CHAR *buffer;
int i1, i2, j;
{
int PRINTED = 0;
register CHAR *bp, *outend;
if(i1 > i2) return 0;
num_of_matched++;
if(COUNT) return 0;
if(SILENT) return 0;
if(OUTTAIL || (!DELIMITER && (D_length == 1) && (D_pattern[0] == '\n')) ) {
if (j>1) i1 = i1 + D_length;
i2 = i2 + D_length;
}
if(DELIMITER) j = j+1;
if(FIRSTOUTPUT) {
if (buffer[i1] == '\n') {
i1++;
EATFIRST = ON;
}
FIRSTOUTPUT = 0;
}
if(TRUNCATE) {
fprintf(stderr, "WARNING! some lines have been truncated in output record #%d\n", num_of_matched-1);
}
/* Why do we have to do this? */
while ((buffer[i1] == '\n') && (i1 <= i2)) {
if (agrep_finalfp != NULL) fprintf(agrep_finalfp, "\n");
else {
if (agrep_outpointer < agrep_outlen)
agrep_outbuffer[agrep_outpointer ++] = '\n';
else {
OUTPUT_OVERFLOW;
return -1;
}
}
i1++;
}
if(FNAME && (NEW_FILE || !POST_FILTER)) {
char nextchar = (POST_FILTER == ON)?'\n':' ';
char *prevstring = (POST_FILTER == ON)?"\n":"";
if (agrep_finalfp != NULL)
fprintf(agrep_finalfp, "%s%s:%c", prevstring, CurrentFileName, nextchar);
else {
int outindex;
if (prevstring[0] != '\0') {
if(agrep_outpointer + 1 >= agrep_outlen) {
OUTPUT_OVERFLOW;
return -1;
}
else agrep_outbuffer[agrep_outpointer ++] = prevstring[0];
}
for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
(CurrentFileName[outindex] != '\0'); outindex++) {
agrep_outbuffer[agrep_outpointer+outindex] = CurrentFileName[outindex];
}
if ((CurrentFileName[outindex] != '\0') || (outindex+agrep_outpointer+2>=agrep_outlen)) {
OUTPUT_OVERFLOW;
return -1;
}
else {
agrep_outbuffer[agrep_outpointer+outindex++] = ':';
agrep_outbuffer[agrep_outpointer+outindex++] = nextchar;
}
agrep_outpointer += outindex;
}
NEW_FILE = OFF;
PRINTED = 1;
}
if(LINENUM) {
if (agrep_finalfp != NULL)
fprintf(agrep_finalfp, "%d: ", j-1);
else {
char s[32];
int outindex;
sprintf(s, "%d: ", j-1);
for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
(s[outindex] != '\0'); outindex++) {
agrep_outbuffer[agrep_outpointer+outindex] = s[outindex];
}
if (s[outindex] != '\0') {
OUTPUT_OVERFLOW;
return -1;
}
agrep_outpointer += outindex;
}
PRINTED = 1;
}
if(BYTECOUNT) {
if (agrep_finalfp != NULL)
fprintf(agrep_finalfp, "%d= ", CurrentByteOffset-1);
else {
char s[32];
int outindex;
sprintf(s, "%d= ", CurrentByteOffset-1);
for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
(s[outindex] != '\0'); outindex++) {
agrep_outbuffer[agrep_outpointer+outindex] = s[outindex];
}
if (s[outindex] != '\0') {
OUTPUT_OVERFLOW;
return -1;
}
agrep_outpointer += outindex;
}
PRINTED = 1;
}
bp = buffer + i1;
outend = buffer + i2;
if (PRINTOFFSET) {
if (agrep_finalfp != NULL)
fprintf(agrep_finalfp, "@%d{%d}\n", CurrentByteOffset - (i2-i1), i2-i1);
else {
char s[32];
int outindex;
sprintf(s, "@%d{%d}\n", CurrentByteOffset - (i2-i1), i2-i1);
for (outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
(s[outindex] != '\0'); outindex ++) {
agrep_outbuffer[agrep_outpointer+outindex] = s[outindex];
}
if (s[outindex] != '\0') {
OUTPUT_OVERFLOW;
return -1;
}
agrep_outpointer += outindex;
}
PRINTED = 1;
}
if (PRINTRECORD) {
if (agrep_finalfp != NULL)
while(bp <= outend) fputc(*bp++, agrep_finalfp);
else {
if (outend - bp + 1 + agrep_outpointer >= agrep_outlen) {
OUTPUT_OVERFLOW;
return -1;
}
while(bp <= outend) agrep_outbuffer[agrep_outpointer ++] = *bp++;
}
}
else if (PRINTED) {
if (agrep_finalfp != NULL) fputc('\n', agrep_finalfp);
else agrep_outbuffer[agrep_outpointer ++] = '\n';
PRINTED = 0;
}
return 0;
}
int
agrep_usage()
{
if (glimpse_call) return -1;
fprintf(stderr, "usage: %s [-#abcdehiklnoprstvwxyBDGIMSV] [-f patternfile] [-H dir] pattern [files]\n", Progname);
fprintf(stderr, "\n");
fprintf(stderr, "summary of frequently used options:\n");
fprintf(stderr, "(For a more detailed listing see 'man agrep'.)\n");
fprintf(stderr, "-#: find matches with at most # errors\n");
fprintf(stderr, "-c: output the number of matched records\n");
fprintf(stderr, "-d: define record delimiter\n");
fprintf(stderr, "-h: do not output file names\n");
fprintf(stderr, "-i: case-insensitive search, e.g., 'a' = 'A'\n");
fprintf(stderr, "-l: output the names of files that contain a match\n");
fprintf(stderr, "-n: output record prefixed by record number\n");
fprintf(stderr, "-v: output those records that have no matches\n");
fprintf(stderr, "-w: pattern has to match as a word, e.g., 'win' will not match 'wind'\n");
fprintf(stderr, "-B: best match mode. find the closest matches to the pattern\n");
fprintf(stderr, "-G: output the files that contain a match\n");
fprintf(stderr, "-H 'dir': the cast-dictionary is located in directory 'dir'\n");
fprintf(stderr, "\n");
if (!EXITONERROR) {
errno = AGREP_ERROR;
return -1;
}
else exit(2);
}